• 締切済み

正三角形内かどうかの判定について

点Aが点Bに触れると, 点A は点Bを取得するというゲームの一部についてです. 座標(x,y)にある点Aが, 点Bを重点とする正三角形の中にあると, 上記のような反応をおこすプログラミングをしたいのですが,(あたり反応と言うらしい?) 正三角形の枠の判定の仕方がわかりません. 何か良いアルゴリズムがあれば教えていただけないでしょうか.

みんなの回答

  • driverII
  • ベストアンサー率27% (248/913)
回答No.4

#3にも誤記が・・・(^^; 3つの頂点の点Aが作る三つの三角形の面積の和が 正三角形と等しい ではなく 3つの頂点のうち2つと点Aが作る三つの三角形の面積の和が正三角形と等しい ですね。 試しにくんでみたら、下記のようになりました ----------------------------------------------- package JavaTest; import JavaTest.Point; class MyJava { public static void main(String ar[]) { Point pInput = new Point(11,1); Point pJu = new Point(0,0); Point pCho = new Point(0,10); String str; boolean fIn = Mathplus.IsIn(pInput,pJu,pCho); if(fIn) { str = "正三角形内"; } else { str = "正三角形外"; } System.out.println(str); } } class Mathplus { public static double degrees(double dR) { return 180 * dR / Math.PI; } public static double radians(double dD) { return Math.PI * dD / 180; } public static double mod(double dA, double dB) { double dR = Math.floor(dA / dB); return dA - dR * dB; } public static boolean IsIn(Point pInput, Point pJu, Point pCho) { double d = pJu.Distance(pCho); double dTheta = Mathplus.mod( 360+90-Mathplus.degrees(Math.atan2(pCho.y,pCho.x)),360); Point pCho2 = new Point( Math.sin(Mathplus.radians(dTheta+120))*(d), Math.cos(Mathplus.radians(dTheta+120))*(d)); Point pCho3 = new Point( Math.sin(Mathplus.radians(dTheta+240))*(d), Math.cos(Mathplus.radians(dTheta+240))*(d)); double dSum = pInput.Distance(pCho,pCho2) + pInput.Distance(pCho2,pCho3) + pInput.Distance(pCho3,pCho); Point pM = new Point((pCho2.x+pCho3.x)/2,(pCho2.y+pCho3.y)/2); double dTakasa = pCho.Distance(pM); return Math.abs(dTakasa - dSum) < 0.00000001; } } ----------------------------------------------- package JavaTest; /** * Pointクラス */ public class Point { public double x,y; public Point() { x = 0; y = 0; } public Point(double px,double py) { x = px; y = py; } public double Distance(Point p1) { double r = Math.sqrt( ((p1.x-this.x)*(p1.x-this.x)+ (p1.y-this.y)*(p1.y-this.y))); return r; } public double Distance(Point p1,Point p2) { Point pT = new Point(0,0); double vec_x, vec_y, alpha,len; vec_x = p2.x-p1.x; vec_y = p2.y-p1.y; alpha = ( vec_x * this.x + vec_y * this.y -vec_x * p1.x - vec_y * p1.y) / (vec_x * vec_x + vec_y * vec_y); if (alpha < 0.0) { len = Distance(p1); } else if (alpha > 1.0) { len = Distance(p2); } else { pT.x = p1.x + vec_x * alpha; pT.y = p1.y + vec_y * alpha; len = Distance(pT); } return len; } } -----------------------------------------------

  • driverII
  • ベストアンサー率27% (248/913)
回答No.3

#2の修正です。 3つの頂点と点Aとの距離の和が一定 ではなく 3つの頂点の点Aが作る三つの三角形の面積の和が 正三角形と等しい = 3辺から点Aとの距離の和が正三角形の高さに等しい ですね・・・

  • driverII
  • ベストアンサー率27% (248/913)
回答No.2

#2では、1つの頂点と重点から、他の2つの頂点を求めるところまで書きます。 重点B(X1,Y1)と1つの頂点(X2,Y2)(C)からは、 1.重点と頂点(C)の距離(D) 2.頂点(C)と重点を結んだ線分のY軸との角度θ 3.他の二つの頂点(E,F)の座標(X3,Y3)(X4,Y4) が求められます。 --------------------------------------------- 1.重点と頂点(C)の距離(D)は =Math.Sqrt((X2-X1)^2+(Y2-Y1)^2) です。 --------------------------------------------- 2.頂点(C)と重点を結んだ線分のY軸との角度θ 5を3で割った余りを2というのを   mod(5,3)=2と表し、 ラジアン値を度に変換するのをdegrees() 逆をradians()と表すとします。 (これらはExcelの関数にもあります。) このとき θ=mod(360+90-degrees(Math.Atan2(X2,Y2)),360) --------------------------------------------- 3.他の二つの頂点(E,F)の座標(X3,Y3)(X4,Y4) X3=Math.sin(radians(θ+120))*(D) Y3=Math.cos(radians(θ+120))*(D) X3=Math.sin(radians(θ+240))*(D) Y3=Math.cos(radians(θ+240))*(D) --------------------------------------------- 以上で全ての頂点の座標が求まりました。 正三角形の中に点A(X,Y)があれば、 3つの頂点と点Aとの距離の和が一定になる筈です。 一定になる距離の和も計算で求められると思いますが、 一旦ここでやめておきます。 (望んでおられる判定方法と違うかもしれないので) もし補足が必要なら書いておいてください。

  • driverII
  • ベストアンサー率27% (248/913)
回答No.1

まぁ、ある点が正三角形にあるか否かを判定する関数なりなんなりを作って、それを呼んであたり判定(反応?)をするんですね。 正三角形で、点B(X1,Y1)の座標がわかっていても、 少なくとも1つの頂点の座標がわからないとどんな(大きさ、向きの)正三角形がわからないと思います。 例えば、必ず△、つまり上が正三角形で、大きさが一定という場合以外は・・・ で、重点と1つの頂点がわかれば、あとの2つの頂点はもとめられますので、あとは判定できそうですね。 今、時間がないのでここまで。 明日までに回答がつかなければ、明日の夜、再度書きます。ごめんなさい。

関連するQ&A