コード例 #1
0
ファイル: GLPolygon.cs プロジェクト: petrj/GLEngineMobile
        public double AngleToVec(GLVector vec)
        {
            // using first three points for creating plane vectors:
            if (Points.Count < 3)
            {
                return(0);
            }
            var plane = GLPlane.CreateFromPoints(Points[0], Points[1], Points[2]);

            var angleToNormal = plane.NormalVector.AngleToVec(vec);

            return(90 - angleToNormal);
        }
コード例 #2
0
ファイル: GLPlane.cs プロジェクト: petrj/GLEngineMobile
        public static GLPlane CreateFromVectorsAndPoint(GLVector u, GLVector v, GLPoint P)
        {
            var plane = new GLPlane();

            plane.Name = "plane";

            plane.Position = P;

            var n = GLVector.CrossProduct(u, v);

            plane.NormalVector = n;

            plane.D = -n.X * P.X - n.Y * P.Y - n.Z * P.Z;

            return(plane);
        }
コード例 #3
0
ファイル: GLPolygon.cs プロジェクト: petrj/GLEngineMobile
        public double DistanceToPoint(GLPoint P)
        {
            // using first three points for creating plane vectors:
            if (Points.Count < 3)
            {
                return(-1);
            }

            var plane = GLPlane.CreateFromPoints(Points[0], Points[1], Points[2]);

            // computing line (made by observer view) - plane cross

            var viewLine = new GLLine();

            viewLine.Position   = P;
            viewLine.LineVector = plane.NormalVector;

            var cross = plane.CrossWithLine(viewLine);

            // geting polygon center to determine right half-plane
            var center = new GLPoint(
                (Points[0].X + Points[1].X + Points[2].X) / 3,
                (Points[0].Y + Points[1].Y + Points[2].Y) / 3,
                (Points[0].Z + Points[1].Z + Points[2].Z) / 3);

            // creating polygon-edge planes:

            //Logger.WriteToLog("Generating edge planes and lines");

            var edgeLines = new List <GLLine>();

            var pointInsideEdgePlanes = true;

            for (var i = 0; i < Points.Count; i++)
            {
                var A = Points[i];
                var B = i + 1 <= Points.Count - 1 ? Points[i + 1] : Points[0];
                var u = new GLVector(A, B);

                var edgePlane = GLPlane.CreateFromVectorsAndPoint(u, plane.NormalVector, A);

                // testing center half-plane position
                var centerInUpperHalfPlane = edgePlane.PointInUpperHalfPlane(center);
                var crossInUpperHalfPlane  = edgePlane.PointInUpperHalfPlane(cross);

                edgeLines.Add(GLLine.CrateFromPoints(A, B));

                if (centerInUpperHalfPlane != crossInUpperHalfPlane)
                {
                    pointInsideEdgePlanes = false;
                    break;
                }
            }

            //Logger.WriteToLog(" cross: " + cross.ToString());

            if (pointInsideEdgePlanes)
            {
                // point inside edge planes
                //Logger.WriteToLog(" point inside edge planes");

                return(cross.DistanceToPoint(P));
            }
            else
            {
                //Logger.WriteToLog("detecting minimal distance to all edge lines");

                var minDistance = double.MaxValue;

                foreach (var line in edgeLines)
                {
                    if (line.LineVector.IsZero)
                    {
                        continue;
                    }

                    var intersectionT = line.IntersectionWithPerpendicularThroughPointParamTValue(P);
                    //Logger.WriteToLog(" intersectionT param value: " + intersectionT.ToString());

                    if (intersectionT == double.MinValue)
                    {
                        return(-1);
                    }

                    if (intersectionT < 0)
                    {
                        // distance to A

                        var distanceToA = P.DistanceToPoint(line.Position);
                        if (distanceToA < minDistance)
                        {
                            minDistance = distanceToA;
                        }
                    }
                    else if (intersectionT > 1)
                    {
                        // distance to B
                        var B           = line.PointByParam(1);
                        var distanceToB = P.DistanceToPoint(B);
                        if (distanceToB < minDistance)
                        {
                            minDistance = distanceToB;
                        }
                    }
                    else
                    {
                        // distance to perpendicular line intersection

                        var intersection   = line.PointByParam(intersectionT);
                        var distanceToLine = P.DistanceToPoint(intersection);
                        if (distanceToLine < minDistance)
                        {
                            minDistance = distanceToLine;
                        }
                    }
                }

                if (minDistance == double.MaxValue)
                {
                    return(-1);
                }

                return(minDistance);
            }
        }