「毎日Unity」の技術ブログ

開発で役立つ情報を発信する

【Processing】頻繁に使用する関数メモ

僕が頻繁に使用する関数を自分用にメモ。

[ 関数一覧 ]

衝突を判別する関数

四角形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;
}