PointやVector3Dクラスには、座標と座標の間の距離を求める同じ名前の静的メソッドdistance()があります。しかし、速さを稼ぐにはこれらのメソッドでなく、Math.sqrt()メソッドを用いて三平方の定理で導く方がお得です。また、このとき各座標値を2乗するのは、Math.pow()メソッドより、単純に変数に入れた座標値を2回掛合わせましょう。
【座標間の距離を求める】
- 座標間の距離はMath.sqrt()メソッドを用いて三平方の定理で計算する
- 数値の2乗はMath.pow()メソッドより同じ変数を2回掛けた方が速い
○04-03-01 Point.distance()とVector3D.distance()メソッド
Point.distance()とVector3D.distance()は、ともに座標と座標の間の距離を求める静的メソッドです。引数には、座標が納められたPointまたはVector3Dインスタンスをふたつ渡します。たとえば、2次元平面上のふたつの座標(1, 1)と(2, 1 + √3)との間の距離は、PointオブジェクトとPoint.distance()を使ってつぎのスクリプト04-03-001のように求めます。
スクリプト04-03-001【○】2次元平面上の2点間の距離をPoint.distance()メソッドで求める
- var begin:Point = new Point(1, 1);
- var end:Point = new Point(2, 1 + Math.sqrt(3));
- var distance:Number = Point.distance(begin, end);
- trace(distance); // 出力: 1.9999999999999998
|
2点間の距離は、正確には2になります。[ムービープレビュー]で[出力]を見ると、計算にはわずかな誤差が含まれているようです。
Vector3D.distance()は、z座標が加わったVector3Dオブジェクトを使うだけで、メソッドの呼出し方は変わりません。座標(1, 1, 1)と(2, 1 + √3, 1)の間の距離は、つぎのスクリプト04-03-002で求まります。ふたつの点のz座標値が同じですので、上記スクリプト04-03-001と同じく距離は2になります。
スクリプト04-03-002【○】3次元空間上の2点間の距離をVector3D.distance()メソッドで求める
- var begin:Vector3D = new Vector3D(1, 1, 1);
- var end:Vector3D = new Vector3D(2, 1 + Math.sqrt(3), 1);
- var distance:Number = Vector3D.distance(begin, end);
- trace(distance); // 出力: 1.9999999999999998
|
これらのメソッドを、決して使っていけないという訳ではありません。ただ、座標は大量に扱うことがめずらしくなく、計算の速さを求めなければならない場合があります。そのようなとき、2点間の距離を求めるのに、Math.sqrt()メソッドで三平方の定理により導くのが有効だということです。
○04-03-02 三平方の定理で2点間の距離を求める
三平方の定理について、簡単におさらいします。すでにおわかりの読者は、この項は飛ばして構いません。
直角三角形の直角を挟んだ2辺の長さをそれぞれaとb、直角に対する斜辺(もっとも長い辺)の長さをcとすると(図04-03-001)、つぎの等式が成立ちます。これを「三平方の定理」あるいは「ピタゴラスの定理」と呼びます。
a2 + b2 = c2
図04-03-001■三平方の定理
a2 + b2 = c2
|
|
直角を挟んだ2辺の長さをaとb、斜辺の長さをcとする。
|
三平方の定理を使うと、2点間の距離を求めることができます。2次元平面上の2点の座標をそれぞれ(x1, y1)および(x2, y2)とし、2点間を結ぶ直線を斜辺とした直角二等辺三角形を考えます(図04-03-002)。すると、直角二等辺三角形の底辺がx1 - x2、高さはy1 - y2になります。よって、2点間の長さをlとしたとき、三平方の定理より、つぎの等式が成立ちます。
l2 = (x1 - x2)2 + (y1 - y2)2
|
|
________________ |
l = √
|
(x1 - x2)2 + (y1 - y2)2
|
図04-03-002■2次元平面上の2点間の距離を三平方の定理で求める

直角を挟む2辺はそれぞれx1 - x2とy1 - y2になる。
|
Tips 04-03-001■距離は0以上の数値
三平方の定理で立てた方程式から両辺の平方根を求めると、方程式そのものの解は正負のふたつが得られます。
l2 = (x1 - x2)2 + (y1 - y2)2
|
|
________________ |
l = ±√
|
(x1 - x2)2 + (y1 - y2)2
|
しかし、求める2点間の距離は0以上で定められますので、本文のとおり正数が解となります。ちなみに「なぜならば」は、数学記号「∵」で表します。
|
________________ |
l = √
|
(x1 - x2)2 + (y1 - y2)2 (∵ l≧0)
|
|
3次元空間ではz座標が加わります。2点の座標をそれぞれ(x1, y1, z1)および(x2, y2, z2)とした場合も、同じように三平方の定理から距離lがつぎの式で導かれます。
|
_________________________ |
l = √
|
(x1 - x2)2 + (y1 - y2)2 + (z1 - z2)2
|
Tips 04-03-002■3次元空間における2点間の距離
3次元空間でふたつの座標の間の距離を求めるには、三平方の定理を2度使います(図04-03-003)。
図04-03-003■3次元空間の2点間の距離を三平方の定理で求める

点A(x2, y2, z2)を通ってy軸と垂直な平面に対して、点B(x1, y1, z1)から垂線を下ろし、点Cとする。
|
まず、点A(x2, y2, z2)を通ってy軸と垂直な平面に対して、点B(x1, y1, z1)から垂線を下ろします。すると、その垂線と平面との交点Cは、座標が(x1, y2, z1)になります。点Cは点Aとy座標値が同じですので、z軸とx軸からなる2次元平面と捉えて、前述の三平方の定理からつぎのようにACの距離が求まります。
|
________________ |
AC = √
|
(x1 - x2)2 + (z1 - z2)2
|
つぎに、三角形ABCは直角三角形ですので、ACとBC(= y1 - y2)から三平方の定理を使ってABが導けます。
AB2 = AC2 + BC2
|
|
________________ |
|
=
|
(√ |
(x1 - x2)2 + (z1 - z2)2 |
)2 + (y1 - y2)2 |
=
|
(x1 - x2)2 + (z1 - z2)2 + (y1 - y2)2 |
|
|
_________________________ |
AB =
|
√ |
(x1 - x2)2 + (y1 - y2)2 + (z1 - z2)2
|
|
○04-03-03 クラスの静的メソッドと同じ仕様で2点間の距離を返す関数の定義
それでは、Math.sqrt()メソッドと三平方の定理により2点間の距離を導くスクリプトについて考えましょう。ふたつのクラスの静的メソッドPoint.distance()とVector3D.distance()と同じ仕様で関数を定めます。
まず。以下のスクリプト04-03-003が、Point.distance()メソッドと同じく、引数として渡したふたつのPointオブジェクトからその間の距離を求めて、Number型で返す関数distance2D()です。引数のPointインスタンスからxy座標をそれぞれ取出して、三平方の定理により距離を求めて返しています。なお、xy各座標の差をそれぞれ2乗するとき、変数に入れた差を単純に2回掛合わせています(第4行目)。この計算の方がMath.pow()メソッドを使うよりも速く、見た目がわかりにくいということもないからです。
Point.distance()メソッドを使った前掲スクリプト04-03-001と同じ座標値で試すと、誤差までまったく同じ値が返されます。
var begin:Point = new Point(1, 1);
var end:Point = new Point(2, 1 + Math.sqrt(3));
var distance:Number = distance2D(begin, end);
trace(distance); // 出力: 1.9999999999999998
|
スクリプト04-03-003【◎】2次元平面の2点間の距離を引数のふたつのPointオブジェクトから求めて返す
- function distance2D(beginPoint:Point, endPoint:Point):Number {
- var nX:Number = endPoint.x - beginPoint.x;
- var nY:Number = endPoint.y - beginPoint.y;
- var distance:Number = Math.sqrt(nX * nX + nY * nY);
- return distance;
- }
|
つぎに、以下のスクリプト04-03-004が、Vector3D.distance()メソッドと同じ仕様の関数distance3D()を定めます。Pointクラスにもとづく前掲スクリプト04-03-003のクラスをVector3Dに替え、z座標値の計算を加えただけです。
こちらもVector3D.distance()メソッドを用いた前掲スクリプト04-03-002と同じ座標値で試せば、戻り値はまったく同じです。
var begin:Vector3D = new Vector3D(1, 1, 1);
var end:Vector3D = new Vector3D(2, 1 + Math.sqrt(3), 1);
var distance:Number = distance3D(begin, end);
trace(distance); // 出力: 1.9999999999999998
|
スクリプト04-03-004【◎】3次元空間の2点間の距離を引数のふたつのVector3Dオブジェクトから求めて返す
- function distance3D(beginVector3D:Vector3D, endVector3D:Vector3D):Number {
- var nX:Number = endVector3D.x - beginVector3D.x;
- var nY:Number = endVector3D.y - beginVector3D.y;
- var nZ:Number = endVector3D.z - beginVector3D.z;
- var distance:Number = Math.sqrt(nX * nX + nY * nY + nZ * nZ);
- return distance;
- }
|
作成者: 野中文雄
作成日: 2011年4月23日