■ マウスがクリックされたxy座標を取得して,スタイルシート上の座標と照合する方法(やや難)

 次の例は,xy平面上で指定された関数が通る点をクリックするものです.この例では,関数(問題)は1つですが,正解とする点の範囲は,クリカブルマップで簡単に指定できるようなものではありません.
 そこで,マウスがクリックされた点のxy座標を取得して,数学座標に変換する方法を取ると,座標平面上のxy座標を利用できるようになります.
 次の例では,茶色で書いた部分は,変更できません.

<例>
 y=x3-3x2 上の点をクリックさせる問題
 
<head>
<style>
.xy_plate
{ position: absolute;
}
</style>
 スタイルシートを利用するのは,xy平面の画像をピクセル単位で正確に置くためです.(マウスがクリックされた点は,これとは別にイベントxy座標で取得します.)
<script language="javascript">
bName = navigator.appName;
bVersion = parseInt(navigator.appVersion);
if(bName == "Netscape" && bVersion >= 4)
 { browser = "N4";
   document.captureEvents(Event.MOUSEDOWN);
   document.mousedown = saiten;
 }
else if(bName == "Microsoft Internet Explorer" && bVersion >= 4)
  browser = "IE4";
navigator.appName−−使用しているブラウザの種類(今はやりのAOLはIEとして動くようです.)
navigator.appVersion−−ブラウザのバージョン(小数と文字)

Netscape Navigator ではキャプチャーするイベントを指定します.

  • 2つ以上のイベントをキャプチャーする場合は | でつなぎます.
  • 次にそれぞれのイベントが生じたときに実行すべき関数名を左記のように書きます.
Internet Explorerではこれらの準備は不要です.
grid = 20;
offsetx1 = 300;
offsety1 = 50;
offsetx2 = 200;
offsety2 = 200;
mx = 0.0;
my = 0.0;
px = 0;
py = 0;
各変数の意味は次の図の通りです.

mx,my−−数学xy座標(yは下がマイナス)
px,py−−ピクセルxy座標
  • この例では1目盛当たり20ピクセルの図を利用しています.

  • (grid=20)
function qf(x)
{return (x * x * x - 3 * x * x);
}
問題とする関数
y=x−3x
function saiten(event)
{if(browser == "N4")
 { px = event.pageX;
   py = event.pageY;
 }
 else if(browser == "IE4")
 { px = event.x;
   py = event.y;
 }
 mx = (px - offsetx1 - offsetx2)/ grid;
 my = (offsety1 + offsety2 - py)/ grid;
 if( Math.abs(my - qf(mx) ) < 1.0)
   document.kekka1.src = "yes.gif";
 else
   document.kekka1.src = "no.gif";
}
</script>
</head>
 NNとIEとではイベントが発生したxy座標の取得方法が異なります.
 

 イベントをページxy座標で取得し,スタイルシートをabsoluteのpx単位で指定しておくと,とりあえず無難に動きます.
 

ページxy座標→数学xy座標の変換

 コンピュータが取り扱う浮動小数点数は近似値です.だから,表現の異なる2つの浮動小数点数が「等しい」とは限りません.(数学的には等しいはずの 0.2+0.2+0.2+0.2+0.2 のような計算結果ですら == 1.0 となるかどうかは運まかせ?)
 そこで,浮動小数点数を比較するには,差が許容範囲内にあるかどうかで調べます.特に傾きが大きいとき,yとf(x)の比較による左記のような方法では,許容範囲 1.0 でも厳し過ぎるでしょう.

<body>
≪問題≫ 次の関数が通る点を1つ示しなさい. y=x<sup>3</sup>-3x<sup>2</sup>
<br><img SRC="white.gif" height=49 width=62 border=0 name="kekka1">
<div class="xy_plate" id="xyheimen" style="position:absolute; left: 300px; top: 50px;"><a href="#" onClick="saiten(event)"><img SRC="xy2.gif" BORDER=0 height=400 width=400></a></div>
</body>
 ここではプログラムを解読しやすくするために,問題数を1題にしています.



実際の見え方→


←覚え書きに戻る  ←←メニューに戻る