僕が頻繁に使用する関数を自分用にメモ。
[ 関数一覧 ]
衝突を判別する関数
四角形ABCDと四角形EFGHが重なっているか判別する関数
boolean QuadrangleIsOnQuadrangle(PVector A, PVector B, PVector C, PVector D, PVector E, PVector F, PVector G, PVector H) { PVector Pos_Center1 = CentralPointFromQuadrangle(A, B, C, D); PVector Pos_Center2 = CentralPointFromQuadrangle(E, F, G, H); float Dist_AB = PVector.dist(A, B); float Dist_AD = PVector.dist(A, D); float Dist_EF = PVector.dist(E, F); float Dist_EH = PVector.dist(E, H); return abs(Pos_Center1.x - Pos_Center2.x) < (Dist_AB / 2) + (Dist_EF / 2) && abs(Pos_Center1.y - Pos_Center2.y) < (Dist_AD / 2) + (Dist_EH / 2); }
三角形ABC内に点Pが存在するか判別する関数
boolean PointIsOnTriangle(PVector P, PVector A, PVector B, PVector C) { PVector Vec_AP = new PVector(P.x - A.x, P.y - A.y); PVector Vec_BP = new PVector(P.x - B.x, P.y - B.y); PVector Vec_CP = new PVector(P.x - C.x, P.y - C.y); PVector Vec_AB = new PVector(B.x - A.x, B.y - A.y); PVector Vec_BC = new PVector(C.x - B.x, C.y - B.y); PVector Vec_CA = new PVector(A.x - C.x, A.y - C.y); PVector Cross_AB_AP = Vec_AB.cross(Vec_AP); PVector Cross_BC_BP = Vec_BC.cross(Vec_BP); PVector Cross_CA_CP = Vec_CA.cross(Vec_CP); return Sign(Cross_AB_AP.z) > 0 && Sign(Cross_BC_BP.z) > 0 && Sign(Cross_CA_CP.z) > 0 || Sign(Cross_AB_AP.z) < 0 && Sign(Cross_BC_BP.z) < 0 && Sign(Cross_CA_CP.z) < 0; }
四角形ABCD内に点Pが存在するか判別する関数
boolean PointIsOnQuadrangle(PVector P, PVector A, PVector B, PVector C, PVector D) { PVector Vec_AP = new PVector(P.x - A.x, P.y - A.y); PVector Vec_BP = new PVector(P.x - B.x, P.y - B.y); PVector Vec_CP = new PVector(P.x - C.x, P.y - C.y); PVector Vec_DP = new PVector(P.x - D.x, P.y - D.y); PVector Vec_AB = new PVector(B.x - A.x, B.y - A.y); PVector Vec_BC = new PVector(C.x - B.x, C.y - B.y); PVector Vec_CD = new PVector(D.x - C.x, D.y - C.y); PVector Vec_DA = new PVector(A.x - D.x, A.y - D.y); PVector Cross_AB_AP = Vec_AB.cross(Vec_AP); PVector Cross_BC_BP = Vec_BC.cross(Vec_BP); PVector Cross_CD_CP = Vec_CD.cross(Vec_CP); PVector Cross_DA_DP = Vec_DA.cross(Vec_DP); return Sign(Cross_AB_AP.z) > 0 && Sign(Cross_BC_BP.z) > 0 && Sign(Cross_CD_CP.z) > 0 && Sign(Cross_DA_DP.z) > 0 || Sign(Cross_AB_AP.z) < 0 && Sign(Cross_BC_BP.z) < 0 && Sign(Cross_CD_CP.z) < 0 && Sign(Cross_DA_DP.z) < 0; }
直線AB上に点Pが存在するか判別する関数
boolean PointIsOnStraightLine(PVector P, PVector A, PVector B) { return (A.y - B.y) * (P.x - A.x) == (A.x - B.x) * (P.y - A.y); }
線分AB上に点Pが存在するか判定する関数
boolean PointIsOnLineSegment(PVector P, PVector A, PVector B) { return max(A.x, B.x) >= P.x && P.x >= min(A.x, B.x) && max(A.y, B.y) >= P.y && P.y >= min(A.y, B.y) && (A.y - B.y) * (P.x - A.x) == (A.x - B.x) * (P.y - A.y); }
線分ABと線分CDが交差しているか判別する関数
boolean LineSegmentIsOnLineSegment(PVector A, PVector B, PVector C, PVector D) { PVector Vec_AB = new PVector(B.x - A.x, B.y - A.y); PVector Vec_AC = new PVector(C.x - A.x, C.y - A.y); PVector Vec_AD = new PVector(D.x - A.x, D.y - A.y); PVector Vec_CA = new PVector(A.x - C.x, A.y - C.y); PVector Vec_CB = new PVector(B.x - C.x, B.y - C.y); PVector Vec_CD = new PVector(D.x - C.x, D.y - C.y); PVector Cross_AB_CD = Vec_AB.cross(Vec_CD); if(Cross_AB_CD.z == 0) { return false; } PVector Cross_AB_AC = Vec_AB.cross(Vec_AC); PVector Cross_AB_AD = Vec_AB.cross(Vec_AD); PVector Cross_CD_CA = Vec_CD.cross(Vec_CA); PVector Cross_CD_CB = Vec_CD.cross(Vec_CB); return Cross_AB_AC.z * Cross_AB_AD.z < 0 && Cross_CD_CA.z * Cross_CD_CB.z < 0; }
距離を求める関数
点AB間のユークリッド距離を求める関数
float EuclideanDist(PVector A, PVector B) { return PVector.dist(A, B); }
点AB間のマンハッタン距離を求める関数
float ManhattanDist(PVector A, PVector B) { return abs(A.x - B.x) + abs(A.y - B.y); }
座標を求める関数
線分ABと線分CDの交点を求める関数
PVector LineSegmentIntersection(PVector A, PVector B, PVector C, PVector D) { PVector Pos_Result = new PVector(0, 0); float V1 = ((D.x - C.x) * (A.y - C.y) - (D.y - C.y) * (A.x - C.x)) / 2; float V2 = ((D.x - C.x) * (C.y - B.y) - (D.y - C.y) * (C.x - B.x)) / 2; Pos_Result.x = A.x + (B.x - A.x) * V1 / (V1 + V2); Pos_Result.y = A.y + (B.y - A.y) * V1 / (V1 + V2); return Pos_Result; }
点Pに最も近い直線AB上に存在する点を求める関数
PVector NearestPosOnStraightLine(PVector P, PVector A, PVector B) { PVector Vec_AB = PVector.sub(B, A); PVector Vec_AP = PVector.sub(P, A); Vec_AB = Vec_AB.normalize(); float Dot_AP_AB = PVector.dot(Vec_AP, Vec_AB); return PVector.add(A, PVector.mult(Vec_AB, Dot_AP_AB)); }
点Pに最も近い線分AB上に存在する点を求める関数
PVector NearestPosOnLineSegment(PVector P, PVector A, PVector B) { PVector Vec_AB = PVector.sub(B, A); PVector Vec_AP = PVector.sub(P, A); float Length_AB = Vec_AB.mag(); Vec_AB = Vec_AB.normalize(); float Dot_AP_AB = PVector.dot(Vec_AP, Vec_AB); Dot_AP_AB = constrain(Dot_AP_AB, 0, Length_AB); return PVector.add(A, PVector.mult(Vec_AB, Dot_AP_AB)); }
点ABCを通る円の中心点(外心)を求める関数
PVector Circumcenter(PVector A, PVector B, PVector C) { PVector Pos_Result = new PVector(0, 0); float SquaredDist_BC = pow(PVector.dist(B, C), 2); float SquaredDist_AC = pow(PVector.dist(A, C), 2); float SquaredDist_AB = pow(PVector.dist(A, B), 2); float V1 = SquaredDist_BC * (-SquaredDist_BC + SquaredDist_AC + SquaredDist_AB); float V2 = SquaredDist_AC * (SquaredDist_BC - SquaredDist_AC + SquaredDist_AB); float V3 = SquaredDist_AB * (SquaredDist_BC + SquaredDist_AC - SquaredDist_AB); Pos_Result = PVector.mult(A, V1); Pos_Result = PVector.add(Pos_Result, PVector.mult(B, V2)); Pos_Result = PVector.add(Pos_Result, PVector.mult(C, V3)); Pos_Result = PVector.div(Pos_Result, (V1 + V2 + V3)); return Pos_Result; }
四角形ABCDの中心点を求める関数
PVector CentralPointFromQuadrangle(PVector A, PVector B, PVector C, PVector D) { PVector Pos_Result = new PVector(0, 0); Pos_Result = PVector.add(Pos_Result, A); Pos_Result = PVector.add(Pos_Result, B); Pos_Result = PVector.add(Pos_Result, C); Pos_Result = PVector.add(Pos_Result, D); Pos_Result = PVector.div(Pos_Result, 4.0); return Pos_Result; }
XY平面で点Aを点Bを中心にV度回転した点を求める関数
PVector RotationMatrix(PVector A, PVector B, float V) { PVector Pos_Result = new PVector(0, 0); Pos_Result.x = (A.x - B.x) * cos(radians(V)) - (A.y - B.y) * sin(radians(V)) + B.x; Pos_Result.y = (A.x - B.x) * sin(radians(V)) + (A.y - B.y) * cos(radians(V)) + B.y; return Pos_Result; }
その他の関数
直線ABと直線CDが垂直か判別する関数
boolean LineSegmentsArePerpendicular(PVector A, PVector B, PVector C, PVector D) { PVector Vec_AB = new PVector(B.x - A.x, B.y - A.y); PVector Vec_CD = new PVector(D.x - C.x, D.y - C.y); return Vec_AB.dot(Vec_CD) == 0; }
直線ABと直線CDが平行か判別する関数
boolean LineSegmentsAreParallel(PVector A, PVector B, PVector C, PVector D) { PVector Vec_AB = new PVector(B.x - A.x, B.y - A.y); PVector Vec_CD = new PVector(D.x - C.x, D.y - C.y); return Vec_AB.dot(new PVector(Vec_CD.y, -Vec_CD.x)) == 0; }
整数Vの符号を返す関数
int Sign(float V) { return V >= 0 ? 1 : -1; }