Ejemplo n.º 1
0
        // calculating normal using Newell's method
        private void CalcNormal(List <Vector3m> points)
        {
            Vector3m normal = Vector3m.Zero();

            for (var i = 0; i < points.Count; i++)
            {
                var j = (i + 1) % (points.Count);
                normal.X += (points[i].Y - points[j].Y) * (points[i].Z + points[j].Z);
                normal.Y += (points[i].Z - points[j].Z) * (points[i].X + points[j].X);
                normal.Z += (points[i].X - points[j].X) * (points[i].Y + points[j].Y);
            }
            Normal = normal;
        }
Ejemplo n.º 2
0
        public bool RaySegmentIntersection(out Vector3m intersection, out Rational distanceSquared, Vector3m linePoint1, Vector3m lineVec1, Vector3m linePoint3, Vector3m linePoint4, Vector3m direction)
        {
            var      lineVec2      = linePoint4 - linePoint3;
            Vector3m lineVec3      = linePoint3 - linePoint1;
            Vector3m crossVec1and2 = lineVec1.Cross(lineVec2);
            Vector3m crossVec3and2 = lineVec3.Cross(lineVec2);

            var res = Misc.PointLineDistance(linePoint3, linePoint4, linePoint1);

            if (res == 0) // line and ray are collinear
            {
                var p    = linePoint1 + lineVec1;
                var res2 = Misc.PointLineDistance(linePoint3, linePoint4, p);
                if (res2 == 0)
                {
                    var s = linePoint3 - linePoint1;
                    if (s.X == direction.X && s.Y == direction.Y && s.Z == direction.Z)
                    {
                        intersection    = linePoint3;
                        distanceSquared = s.LengthSquared();
                        return(true);
                    }
                }
            }
            //is coplanar, and not parallel
            if (/*planarFactor == 0.0f && */ crossVec1and2.LengthSquared() > 0)
            {
                var s = crossVec3and2.Dot(crossVec1and2) / crossVec1and2.LengthSquared();
                if (s >= 0)
                {
                    intersection    = linePoint1 + (lineVec1 * s);
                    distanceSquared = (lineVec1 * s).LengthSquared();
                    if ((intersection - linePoint3).LengthSquared() + (intersection - linePoint4).LengthSquared() <=
                        lineVec2.LengthSquared())
                    {
                        return(true);
                    }
                }
            }
            intersection    = Vector3m.Zero();
            distanceSquared = 0;
            return(false);
        }
Ejemplo n.º 3
0
        public void Triangulate()
        {
            if (Normal.Equals(Vector3m.Zero()))
            {
                throw new Exception("The input is not a valid polygon");
            }
            if (_holes != null && _holes.Count > 0)
            {
                ProcessHoles();
            }

            List <ConnectionEdge> nonConvexPoints = FindNonConvexPoints(_mainPointList);

            if (nonConvexPoints.Count == _mainPointList.PointCount)
            {
                throw new ArgumentException("The triangle input is not valid");
            }

            while (_mainPointList.PointCount > 2)
            {
                bool guard = false;
                foreach (var cur in _mainPointList.GetPolygonCirculator())
                {
                    if (!IsConvex(cur))
                    {
                        continue;
                    }

                    if (!IsPointInTriangle(cur.Prev.Origin, cur.Origin, cur.Next.Origin, nonConvexPoints))
                    {
                        // cut off ear
                        guard = true;
                        Result.Add(cur.Prev.Origin);
                        Result.Add(cur.Origin);
                        Result.Add(cur.Next.Origin);

                        // Check if prev and next are still nonconvex. If not, then remove from non convex list
                        if (IsConvex(cur.Prev))
                        {
                            int index = nonConvexPoints.FindIndex(x => x == cur.Prev);
                            if (index >= 0)
                            {
                                nonConvexPoints.RemoveAt(index);
                            }
                        }
                        if (IsConvex(cur.Next))
                        {
                            int index = nonConvexPoints.FindIndex(x => x == cur.Next);
                            if (index >= 0)
                            {
                                nonConvexPoints.RemoveAt(index);
                            }
                        }
                        _mainPointList.Remove(cur);
                        break;
                    }
                }

                if (PointsOnLine(_mainPointList))
                {
                    break;
                }
                if (!guard)
                {
                    throw new Exception("No progression. The input must be wrong");
                }
            }
        }