うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

クリック/タップ位置の取得方法 全解説

アプレット内に作成すべきオブジェクト

数値オブジェクト pageX, pageY, ratioX, ratioY, rectX, rectY

※いずれも値は任意;最大値、最小値は限定しないでおく。

 

点オブジェクト A

A = PixelPoint[(pageX - rectX) / ratioX, (pageY - rectY) / ratioY]

オリジナルツールPixelPointの導入が必要です。

 

グローバルJavaスクリプトの内容
var frame = 0;
var appType = location.href.split('/')[3];  //m(生徒向けワークシート)、worksheet(編集・アップロード画面)、classic(GeoGebra Classic)、material(iframe埋め込み)を判別

function ggbOnInit() {
  requestAnimationFrame(ggbOnInit);
  // フレーム数をインクリメント
  frame++;
  // フレーム数が30で割り切れなければ以下を実行しない
  if(frame % 30 != 0) { return; }
  var clickOrTouchStart = 
  window.ontouchstart===null?'touchstart':'click';  // タッチデバイスならtouchstart、マウスデバイスならclick
  if(location.href.split('/')[3] == 'classic'){
    var canvas = document.getElementsByTagName('canvas')[1];  //GeoGebra Classicで開き、かつ数式ビューが表示されている場合を前提としています。
  }
  else{
    var canvas = document.getElementsByTagName('canvas')[0];
  }
  canvas.addEventListener(clickOrTouchStart,pixelPicker);
}

function pixelPicker(e){

  // pageXY
  var pageX = e.pageX;
  var pageY = e.pageY;

  // グラフィックスビューの相対位置
  if(location.href.split('/')[3] == 'classic'){
    var canvas = document.getElementsByTagName('canvas')[1];  //GeoGebra Classicで開き、かつ数式ビューが表示されている場合を前提としています。
  }
  else{
    var canvas = document.getElementsByTagName('canvas')[0];
  }
  var clientRect = canvas.getBoundingClientRect();
  var rectX = window.pageXOffset + clientRect.left;  // スクロールした分+今表示されているウインドウからの距離
  var rectY = window.pageYOffset + clientRect.top;

  // スケール
  var ratioX;
  var ratioY;
  var transformText = document.getElementsByClassName('applet_scaler')[0];
  if(typeof transformText === 'undefined'){
    transformText = 'none';
  }  // applet_scalerがundefinedの場合には、縮尺1の場合として対応
  else{
    transformText = transformText.style.transform;  // 'none'または'scale(数値1, 数値2)'
  }
  if(transformText == 'none'){
    ratioX = 1;
    ratioY = 1;
  }  // 縮尺1のとき
  else{
    var editedText = transformText.slice(6,-1);  // '数値1, 数値2'
    ratioX = eval('['+editedText+']')[0];  // 数値1
    ratioY = eval('['+editedText+']')[1];  // 数値2
  }

  //アプレットへ値を書き出し
  ggbApplet.setValue('pageX', pageX);
  ggbApplet.setValue('pageY', pageY);
  ggbApplet.setValue('rectX', rectX);
  ggbApplet.setValue('rectY', rectY);
  ggbApplet.setValue('ratioX', ratioX);
  ggbApplet.setValue('ratioY', ratioY);
}

 

現在の縮尺に最適なグリッド間隔を取得するオリジナルツール「GridIntervalPoint」

はじめに

GeoGebraでは、グリッド間隔を特に指定しなければ、現在の縮尺に最適な間隔を自動で計算して、グリッドを描画してくれます。

f:id:usiblog:20180609210456g:plain

今回は、このときのグリッド間隔の情報を取得するオリジナルツールを紹介します。

 

オリジナルツール「GridIntervalPoint」

GridIntervalPoint Tool - GeoGebra

引数

GridIntervalPoint[ <始点A>, <整数n> ]

戻り値

点Aを通るグリッドで、現在の縮尺に最適なグリッドを引いた場合に、始点を通る縦グリッドのn個右のグリッドと、始点を通る横グリッドのn個上のグリッドとの交点を返します。

f:id:usiblog:20180609211523g:plain

 

使用例

点 O, A, C1, C3を、以下の定義に従って作成します。

O = (0, 0)

A = GridIntervalPoint[O, 1]

C1 = Corner[1]

C3 = Corner[3]

変数 minX, maxX, minY, maxYを、以下の定義に従って作成します。

minX = floor( x(C1) / x(A) )

maxX = ceil( x(C3) / x(A) )

minY = floor( y(C1) / y(A) )

maxY = ceil( y(C3) / y(A) )

リスト list1を、以下の定義に従って作成します。

list1 = Flatten[ { Sequence[ x = x( GridIntervalPoint[ O, s ] ), s, minX, maxX ], Sequence[ y = y( GridIntervalPoint[ O, t ] ), t, minY, maxY ] } ]

すると、list1は、現在の縮尺に最適なグリッドを表すオブジェクトとなります。

f:id:usiblog:20180609212739g:plain

 

また、リスト list2を、以下の定義に従って作成します。

list2 = Flatten[ Sequence[ Sequence[ ( x( GridIntervalPoint[ O, s ] ), y( GridIntervalPoint[ O, t ] ) ), t, minY, maxY ], s, minX, maxX ] ]

すると、list2は、現在の縮尺に最適なグリッドの格子点のリストを表します。

f:id:usiblog:20180609220207g:plain