Esempio n. 1
0
    private float SegmentToSegmentClosestPoint(geoLine Line1, geoLine Line2, ref geoPoint ClosestPt1, ref geoPoint ClosestPt2)
    {
        geoPoint pt1 = null;
        geoPoint pt2 = null;
        geoPoint pt3 = null;
        geoPoint pt4 = null;

        pt1 = Line1.P1;
        pt2 = Line1.P2;
        pt3 = Line2.P1;
        pt4 = Line2.P2;

        // using arrays for saving differencess
        geoPoint u = new geoPoint(pt2.X - pt1.X, pt2.Y - pt1.Y, pt2.Z - pt1.Z);
        geoPoint v = new geoPoint(pt4.X - pt3.X, pt4.Y - pt3.Y, pt4.Z - pt3.Z);
        geoPoint w = new geoPoint(pt1.X - pt3.X, pt1.Y - pt3.Y, pt1.Z - pt3.Z);

        float a = u.X * u.X + u.Y * u.Y + u.Z * u.Z;
        //U.U>=0
        float b = u.X * v.X + u.Y * v.Y + u.Z * v.Z;
        //U.V
        float c = v.X * v.X + v.Y * v.Y + v.Z * v.Z;
        //V.V>=0
        float d = u.X * w.X + u.Y * w.Y + u.Z * w.Z;
        //U.W
        float e = v.X * w.X + v.Y * w.Y + v.Z * w.Z;
        //V.W

        float D_ = a * c - b * b;
        // >=0

        float sN = D_;
        float sD = D_;
        float tN = D_;
        float tD = D_;
        float sc = D_;
        float tc = D_;


        if (D_ < 1E-13)
        {
            //PARALLEL
            sN = 0;
            sD = 1;
            tN = e;
            tD = c;
        }
        else
        {
            //Inifinite
            sN = (b * e) - (c * d);
            tN = (a * e) - (b * d);
            if (sN < 0)
            {
                sN = 0;
                tN = e;
                tD = c;
            }
            else if (sN > sD)
            {
                sN = sD;
                tN = e + b;
                tD = c;
            }
        }

        if (tN < 0)
        {
            tN = 0;
            if (-d < 0)
            {
                sN = 0;
            }
            else if (-d > a)
            {
                sN = sD;
            }
            else
            {
                sN = -d;
                sD = a;
            }
        }
        else if (tN > tD)
        {
            tN = tD;
            if ((-d + b) < 0)
            {
                sN = 0;
            }
            else if ((-d + b) > a)
            {
                sN = sD;
            }
            else
            {
                sN = (-d + b);
                sD = a;
            }
        }

        sc = sN / sD;
        tc = tN / tD;

        geoPoint dp = new geoPoint(w.X + sc * u.X - v.X * tc, w.Y + sc * u.Y - v.Y * tc, w.Z + sc * u.Z - v.Z * tc);

        //Dim dis As float = Math.Sqrt(dp.X * dp.X + dp.Y * dp.Y + dp.Z * dp.Z)

        ClosestPt1 = new geoPoint(pt1.X + sc * u.X, pt1.Y + sc * u.Y, pt1.Z + sc * u.Z);

        ClosestPt2 = new geoPoint(pt3.X + tc * v.X, pt3.Y + tc * v.Y, pt3.Z + tc * v.Z);

        return(ClosestPt1.distance(ref ClosestPt2));
    }
Esempio n. 2
0
    public float distance(GameObject obj1, GameObject obj2)
    {
        Mesh mesh1 = obj1.GetComponent <MeshFilter>().mesh;
        Mesh mesh2 = obj2.GetComponent <MeshFilter>().mesh;

        Vector3[] vertices1 = mesh1.vertices;
        Vector3[] vertices2 = mesh2.vertices;

        Vector3 pos1 = obj1.transform.position;
        Vector3 scl1 = obj1.transform.localScale;

        Vector3 pos2 = obj2.transform.position;
        Vector3 scl2 = obj2.transform.localScale;



        for (int i = 0; i < vertices1.Length; i++)
        {
            Quaternion rotation = Quaternion.Euler(obj1.transform.rotation.eulerAngles);

            vertices1[i] = rotation * vertices1[i];

            vertices1 [i].x = vertices1 [i].x * scl1.x;
            vertices1 [i].y = vertices1 [i].y * scl1.y;
            vertices1 [i].z = vertices1 [i].z * scl1.z;

            vertices1[i] += pos1;
        }


        for (int j = 0; j < vertices2.Length; j++)
        {
            Quaternion rotation = Quaternion.Euler(obj2.transform.rotation.eulerAngles);

            vertices2[j] = rotation * vertices2[j];

            vertices2 [j].x = vertices2 [j].x * scl2.x;
            vertices2 [j].y = vertices2 [j].y * scl2.y;
            vertices2 [j].z = vertices2 [j].z * scl2.z;

            vertices2[j] += pos2;
        }


        float MinClearance;
        float distance;

        geoPoint Obj1ClosestPoint = new geoPoint();
        geoPoint Obj2ClosestPoint = new geoPoint();

        geoPoint[] Obj1Points = new geoPoint[4];
        geoPoint[] Obj2Points = new geoPoint[4];
        geoLine[]  Obj1Lines  = new geoLine[4];
        geoLine[]  Obj2Lines  = new geoLine[4];


        MinClearance = 1000;


        for (int i = 0; i < vertices1.Length; i += 4)
        {
            for (int j = 0; j < vertices2.Length; j += 4)
            {
                Obj1Points[0] = new geoPoint(vertices1[i].x, vertices1[i].y, vertices1[i].z);
                Obj1Points[1] = new geoPoint(vertices1[i + 1].x, vertices1[i + 1].y, vertices1[i + 1].z);
                Obj1Points[2] = new geoPoint(vertices1[i + 2].x, vertices1[i + 2].y, vertices1[i + 2].z);
                Obj1Points[3] = new geoPoint(vertices1[i + 3].x, vertices1[i + 3].y, vertices1[i + 3].z);

                Obj2Points[0] = new geoPoint(vertices2[j].x, vertices2[j].y, vertices2[j].z);
                Obj2Points[1] = new geoPoint(vertices2[j + 1].x, vertices2[j + 1].y, vertices2[j + 1].z);
                Obj2Points[2] = new geoPoint(vertices2[j + 2].x, vertices2[j + 2].y, vertices2[j + 2].z);
                Obj2Points[3] = new geoPoint(vertices2[j + 3].x, vertices2[j + 3].y, vertices2[j + 3].z);

                Obj1Lines[0] = new geoLine(Obj1Points[0], Obj1Points[1]);
                Obj1Lines[1] = new geoLine(Obj1Points[1], Obj1Points[2]);
                Obj1Lines[2] = new geoLine(Obj1Points[2], Obj1Points[3]);
                Obj1Lines[3] = new geoLine(Obj1Points[3], Obj1Points[0]);

                Obj2Lines[0] = new geoLine(Obj2Points[0], Obj2Points[1]);
                Obj2Lines[1] = new geoLine(Obj2Points[1], Obj2Points[2]);
                Obj2Lines[2] = new geoLine(Obj2Points[2], Obj2Points[3]);
                Obj2Lines[3] = new geoLine(Obj2Points[3], Obj2Points[0]);


                distance = List_PointPolygonClosestDistances(Obj1Points, Obj2Points, ref Obj2ClosestPoint, ref Obj1ClosestPoint);
                if (distance < MinClearance)
                {
                    MinClearance = distance;
                }

                distance = List_SegmentSegmentClosestDistance(Obj1Lines, Obj2Lines, ref Obj1ClosestPoint, ref Obj2ClosestPoint);

                if (distance < MinClearance)
                {
                    MinClearance = distance;
                }

                distance = List_PointPolygonClosestDistances(Obj2Points, Obj1Points, ref Obj2ClosestPoint, ref Obj1ClosestPoint);

                if (distance < MinClearance)
                {
                    MinClearance = distance;
                }
            }
        }

        return(MinClearance);
    }