Esempio n. 1
0
        public void PlaneConstructionTest()
        {
            var p1 = new Coordinate(-100, -100, 100);
            var p2 = new Coordinate(100, -100, 100);
            var p3 = new Coordinate(100, 100, 100);
            var p4 = new Coordinate(0, 0, 0);
            var refPlane = new Plane(new Coordinate(0, 0, 1), 100);
            var plane = new Plane(p3, p2, p1);

            var o1 = refPlane.OnPlane(p1);
            var o2 = plane.OnPlane(p1);
            var o3 = refPlane.OnPlane(p4);
            var o4 = plane.OnPlane(p4);

            Assert.IsTrue(o1 == 0);
            Assert.IsTrue(o2 == 0);
            Assert.IsFalse(o3 == 0);
            Assert.IsFalse(o4 == 0);

            Assert.AreEqual(refPlane.A, plane.A);
            Assert.AreEqual(refPlane.B, plane.B);
            Assert.AreEqual(refPlane.C, plane.C);
            Assert.AreEqual(refPlane.D, plane.D);

            var plane2 = new Plane(new Coordinate(-192, 704, 192),
                                   new Coordinate(-192, 320, 192),
                                   new Coordinate(-192, 320, -192));
        }
Esempio n. 2
0
File: Line.cs Progetto: silky/sledge
        /// <summary>
        /// Determines if this line is behind, in front, or spanning a plane.
        /// </summary>
        /// <param name="p">The plane to test against</param>
        /// <returns>A PlaneClassification value.</returns>
        public PlaneClassification ClassifyAgainstPlane(Plane p)
        {
            var start = p.OnPlane(Start);
            var end = p.OnPlane(End);

            if (start == 0 && end == 0) return PlaneClassification.OnPlane;
            if (start <= 0 && end <= 0) return PlaneClassification.Back;
            if (start >= 0 && end >= 0) return PlaneClassification.Front;
            return PlaneClassification.Spanning;
        }
Esempio n. 3
0
        /// <summary>
        /// Determines if this polygon is behind, in front, or spanning a plane.
        /// </summary>
        /// <param name="p">The plane to test against</param>
        /// <returns>A PlaneClassification value.</returns>
        public PlaneClassification ClassifyAgainstPlane(Plane p)
        {
            int front = 0, back = 0, onplane = 0, count = Vertices.Count;

            foreach (var test in Vertices.Select(x => p.OnPlane(x)))
            {
                // Vertices on the plane are both in front and behind the plane in this context
                if (test <= 0)
                {
                    back++;
                }
                if (test >= 0)
                {
                    front++;
                }
                if (test == 0)
                {
                    onplane++;
                }
            }

            if (onplane == count)
            {
                return(PlaneClassification.OnPlane);
            }
            if (front == count)
            {
                return(PlaneClassification.Front);
            }
            if (back == count)
            {
                return(PlaneClassification.Back);
            }
            return(PlaneClassification.Spanning);
        }
Esempio n. 4
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. 5
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. 6
0
        /// <summary>
        /// Determines if this line is behind, in front, or spanning a plane.
        /// </summary>
        /// <param name="p">The plane to test against</param>
        /// <returns>A PlaneClassification value.</returns>
        public PlaneClassification ClassifyAgainstPlane(Plane p)
        {
            var start = p.OnPlane(Start);
            var end   = p.OnPlane(End);

            if (start == 0 && end == 0)
            {
                return(PlaneClassification.OnPlane);
            }
            if (start <= 0 && end <= 0)
            {
                return(PlaneClassification.Back);
            }
            if (start >= 0 && end >= 0)
            {
                return(PlaneClassification.Front);
            }
            return(PlaneClassification.Spanning);
        }
Esempio n. 7
0
        /// <summary>
        /// Determines if this polygon is behind, in front, or spanning a plane.
        /// </summary>
        /// <param name="p">The plane to test against</param>
        /// <returns>A PlaneClassification value.</returns>
        public PlaneClassification ClassifyAgainstPlane(Plane p)
        {
            int front = 0, back = 0, onplane = 0, count = Vertices.Count;

            foreach (var test in Vertices.Select(x => p.OnPlane(x)))
            {
                // Vertices on the plane are both in front and behind the plane in this context
                if (test <= 0) back++;
                if (test >= 0) front++;
                if (test == 0) onplane++;
            }

            if (onplane == count) return PlaneClassification.OnPlane;
            if (front == count) return PlaneClassification.Front;
            if (back == count) return PlaneClassification.Back;
            return PlaneClassification.Spanning;
        }
Esempio n. 8
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. 9
0
        /// <summary>
        /// Determines if this polygon is behind, in front, or spanning a plane.
        /// </summary>
        /// <param name="p">The plane to test against</param>
        /// <returns>A PlaneClassification value.</returns>
        public PlaneClassification ClassifyAgainstPlane(Plane p)
        {
            var count   = Vertices.Count;
            var front   = 0;
            var back    = 0;
            var onplane = 0;

            foreach (var t in Vertices)
            {
                var test = p.OnPlane(t);

                // Vertices on the plane are both in front and behind the plane in this context
                if (test <= 0)
                {
                    back++;
                }
                if (test >= 0)
                {
                    front++;
                }
                if (test == 0)
                {
                    onplane++;
                }
            }

            if (onplane == count)
            {
                return(PlaneClassification.OnPlane);
            }
            if (front == count)
            {
                return(PlaneClassification.Front);
            }
            if (back == count)
            {
                return(PlaneClassification.Back);
            }
            return(PlaneClassification.Spanning);
        }
Esempio n. 10
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. 11
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. 12
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);
        }