Esempio n. 1
0
        private void RenderLine(Vector3 start, Vector3 end, Plane plane, Color color, ICamera camera, Graphics graphics)
        {
            var line = new Line(start, end);
            var cls  = line.ClassifyAgainstPlane(plane);

            if (cls == PlaneClassification.Back)
            {
                return;
            }
            if (cls == PlaneClassification.Spanning)
            {
                var isect = plane.GetIntersectionPoint(line, true);
                var first = plane.OnPlane(line.Start) > 0 ? line.Start : line.End;
                if (!isect.HasValue)
                {
                    return;
                }
                line = new Line(first, isect.Value);
            }

            var st = camera.WorldToScreen(line.Start);
            var en = camera.WorldToScreen(line.End);

            using (var p = new Pen(color, 2))
            {
                graphics.DrawLine(p, st.X, st.Y, en.X, en.Y);
            }
        }
Esempio n. 2
0
        private void RenderLine(Vector3 start, Vector3 end, Plane plane, Color color, ICamera camera, I2DRenderer im)
        {
            var line = new Line(start, end);
            var cls  = line.ClassifyAgainstPlane(plane);

            if (cls == PlaneClassification.Back)
            {
                return;
            }
            if (cls == PlaneClassification.Spanning)
            {
                var isect = plane.GetIntersectionPoint(line, true);
                var first = plane.OnPlane(line.Start) > 0 ? line.Start : line.End;
                if (!isect.HasValue)
                {
                    return;
                }
                line = new Line(first, isect.Value);
            }

            var st = camera.WorldToScreen(line.Start);
            var en = camera.WorldToScreen(line.End);

            im.AddLine(st.ToVector2(), en.ToVector2(), color, 2);
        }
Esempio n. 3
0
        private void AddLine(CircleType type, Vector3 start, Vector3 end, Plane test, CachedLines cache)
        {
            var line = new Line(start, end);
            var cls  = line.ClassifyAgainstPlane(test);

            if (cls == PlaneClassification.Back)
            {
                return;
            }
            if (cls == PlaneClassification.Spanning)
            {
                var isect = test.GetIntersectionPoint(line, true);
                var first = test.OnPlane(line.Start) > 0 ? line.Start : line.End;
                if (isect.HasValue)
                {
                    line = new Line(first, isect.Value);
                }
            }
            cache.Cache[type].Add(new Line(cache.Viewport.Camera.WorldToScreen(line.Start), cache.Viewport.Camera.WorldToScreen(line.End)));
        }
Esempio n. 4
0
        /// <summary>
        /// Splits this polygon by a clipping plane, returning the back and front planes.
        /// The original polygon is not modified.
        /// </summary>
        /// <param name="clip">The clipping plane</param>
        /// <param name="back">The back polygon</param>
        /// <param name="front">The front polygon</param>
        /// <returns>True if the split was successful</returns>
        public bool Split(Plane clip, out Polygon back, out Polygon front)
        {
            // If the polygon doesn't span the plane, return false.
            var classify = ClassifyAgainstPlane(clip);
            if (classify != PlaneClassification.Spanning)
            {
                back = front = null;
                if (classify == PlaneClassification.Back) back = this;
                else if (classify == PlaneClassification.Front) front = this;
                return false;
            }

            // Get the new front and back vertices
            var backVerts = new List<Coordinate>();
            var frontVerts = new List<Coordinate>();
            var prev = 0;

            for (var i = 0; i <= Vertices.Count; i++)
            {
                var end = Vertices[i % Vertices.Count];
                var cls = clip.OnPlane(end);

                // Check plane crossing
                if (i > 0 && cls != 0 && prev != 0 && prev != cls)
                {
                    // This line end point has crossed the plane
                    // Add the line intersect to the
                    var start = Vertices[i - 1];
                    var line = new Line(start, end);
                    var isect = clip.GetIntersectionPoint(line, true);
                    if (isect == null) throw new Exception("Expected intersection, got null.");
                    frontVerts.Add(isect);
                    backVerts.Add(isect);
                }

                // Add original points
                if (i < Vertices.Count)
                {
                    // OnPlane points get put in both polygons, doesn't generate split
                    if (cls >= 0) frontVerts.Add(end);
                    if (cls <= 0) backVerts.Add(end);
                }

                prev = cls;
            }

            back = new Polygon(backVerts);
            front = new Polygon(frontVerts);

            return true;
        }
Esempio n. 5
0
File: Face.cs Progetto: silky/sledge
        protected static Coordinate GetIntersectionPoint(IList<Coordinate> coordinates, Line line, bool ignoreDirection = false)
        {
            var plane = new Plane(coordinates[0], coordinates[1], coordinates[2]);
            var intersect = plane.GetIntersectionPoint(line, ignoreDirection);
            if (intersect == null) return null;

            // http://paulbourke.net/geometry/insidepoly/

            // The angle sum will be 2 * PI if the point is inside the face
            double sum = 0;
            for (var i = 0; i < coordinates.Count; i++)
            {
                var i1 = i;
                var i2 = (i + 1) % coordinates.Count;

                // Translate the vertices so that the intersect point is on the origin
                var v1 = coordinates[i1] - intersect;
                var v2 = coordinates[i2] - intersect;

                var m1 = v1.VectorMagnitude();
                var m2 = v2.VectorMagnitude();
                var nom = m1 * m2;
                if (nom < 0.001m)
                {
                    // intersection is at a vertex
                    return intersect;
                }
                sum += Math.Acos((double)(v1.Dot(v2) / nom));
            }

            var delta = Math.Abs(sum - Math.PI * 2);
            return (delta < 0.001d) ? intersect : null;
        }
Esempio n. 6
0
 private void AddLine(CircleType type, Coordinate start, Coordinate end, Plane test, CachedLines cache)
 {
     var line = new Line(start, end);
     var cls = line.ClassifyAgainstPlane(test);
     if (cls == PlaneClassification.Back) return;
     if (cls == PlaneClassification.Spanning)
     {
         var isect = test.GetIntersectionPoint(line, true);
         var first = test.OnPlane(line.Start) > 0 ? line.Start : line.End;
         line = new Line(first, isect);
     }
     cache.Cache[type].Add(new Line(cache.Viewport3D.WorldToScreen(line.Start), cache.Viewport3D.WorldToScreen(line.End)));
 }
Esempio n. 7
0
        /// <summary>
        /// Splits this polygon by a clipping plane, returning the back and front planes.
        /// The original polygon is not modified.
        /// </summary>
        /// <param name="clip">The clipping plane</param>
        /// <param name="back">The back polygon</param>
        /// <param name="front">The front polygon</param>
        /// <param name="coplanarBack">If the polygon rests on the plane and points backward, this will not be null</param>
        /// <param name="coplanarFront">If the polygon rests on the plane and points forward, this will not be null</param>
        /// <returns>True if the split was successful</returns>
        public bool Split(Plane clip, out Polygon back, out Polygon front, out Polygon coplanarBack, out Polygon coplanarFront)
        {
            // If the polygon doesn't span the plane, return false.
            var classify = ClassifyAgainstPlane(clip);

            if (classify != PlaneClassification.Spanning)
            {
                back         = front = null;
                coplanarBack = coplanarFront = null;
                if (classify == PlaneClassification.Back)
                {
                    back = this;
                }
                else if (classify == PlaneClassification.Front)
                {
                    front = this;
                }
                else if (Plane.Normal.Dot(clip.Normal) > 0)
                {
                    coplanarFront = this;
                }
                else
                {
                    coplanarBack = this;
                }
                return(false);
            }

            // Get the new front and back vertices
            var backVerts  = new List <Coordinate>();
            var frontVerts = new List <Coordinate>();
            var prev       = 0;

            for (var i = 0; i <= Vertices.Count; i++)
            {
                var end = Vertices[i % Vertices.Count];
                var cls = clip.OnPlane(end);

                // Check plane crossing
                if (i > 0 && cls != 0 && prev != 0 && prev != cls)
                {
                    // This line end point has crossed the plane
                    // Add the line intersect to the
                    var start = Vertices[i - 1];
                    var line  = new Line(start, end);
                    var isect = clip.GetIntersectionPoint(line, true);
                    if (isect == null)
                    {
                        throw new Exception("Expected intersection, got null.");
                    }
                    frontVerts.Add(isect);
                    backVerts.Add(isect);
                }

                // Add original points
                if (i < Vertices.Count)
                {
                    // OnPlane points get put in both polygons, doesn't generate split
                    if (cls >= 0)
                    {
                        frontVerts.Add(end);
                    }
                    if (cls <= 0)
                    {
                        backVerts.Add(end);
                    }
                }

                prev = cls;
            }

            back         = new Polygon(backVerts);
            front        = new Polygon(frontVerts);
            coplanarBack = coplanarFront = null;

            return(true);
        }
Esempio n. 8
0
        public void PlaneLineIntersectionTest()
        {
            var plane = new Plane(new Coordinate(0, 0, 1), 100);

            var passLine = new Line(new Coordinate(0, 0, 0), new Coordinate(0, 0, 200));
            var reversePassLine = passLine.Reverse();
            var failSegment = new Line(new Coordinate(0, 0, 0), new Coordinate(0, 0, 50));
            var failLine = new Line(new Coordinate(0, 0, 0), new Coordinate(1, 0, 0));

            var pass1 = plane.GetIntersectionPoint(passLine);
            var pass2 = plane.GetIntersectionPoint(reversePassLine, true);
            var pass3 = plane.GetIntersectionPoint(failSegment, false, true);

            var fail1 = plane.GetIntersectionPoint(reversePassLine);
            var fail2 = plane.GetIntersectionPoint(failSegment);
            var fail3 = plane.GetIntersectionPoint(failLine);

            Assert.IsNotNull(pass1);
            Assert.IsNotNull(pass2);
            Assert.IsNotNull(pass3);
            Assert.IsNull(fail1);
            Assert.IsNull(fail2);
            Assert.IsNull(fail3);
        }