예제 #1
0
파일: Intersect.cs 프로젝트: biorpg/RT.Util
        /// <summary>
        ///     Calculates the intersection of a ray with a segment. Returns the result as the lambdas of the intersection
        ///     point along the ray and the segment. If there is no intersection returns double.NaN in both lambdas.</summary>
        public static void RayWithSegment(ref EdgeD ray, ref EdgeD segment, out double rayL, out double segmentL)
        {
            Intersect.LineWithLine(ref ray, ref segment, out rayL, out segmentL);

            if (!double.IsNaN(rayL) && ((rayL < 0) || (segmentL < 0) || (segmentL > 1)))
            {
                rayL = segmentL = double.NaN;
            }
        }
예제 #2
0
        private void AssertRayWithCircle(double frX, double frY, double toX, double toY, double cX, double cY, double cR, double expL1, double expL2)
        {
            EdgeD   ray = new EdgeD(frX, frY, toX, toY);
            CircleD cir = new CircleD(cX, cY, cR);
            double  l1, l2;

            Intersect.RayWithCircle(ref ray, ref cir, out l1, out l2);
            Assert.AreEqual(expL1, l1, 0.001);
            Assert.AreEqual(expL2, l2, 0.001);
        }
예제 #3
0
        private void AssertLineWithCircle(double frX, double frY, double toX, double toY, double cX, double cY, double cR, double expL1, double expL2)
        {
            EdgeD   lin = new EdgeD(frX, frY, toX, toY);
            CircleD cir = new CircleD(cX, cY, cR);
            double  l1, l2;

            Intersect.LineWithCircle(ref lin, ref cir, out l1, out l2);
            Assert.AreEqual(MinTO(expL1, expL2), MinTO(l1, l2), 0.001);
            Assert.AreEqual(MaxTO(expL1, expL2), MaxTO(l1, l2), 0.001);
        }
예제 #4
0
파일: Intersect.cs 프로젝트: biorpg/RT.Util
        /// <summary>
        ///     Finds intersections between a ray and a rectangle. Returns the lambdas of intersections, if any, or NaN
        ///     otherwise. Guarantees that lambda1 &lt; lambda2, and if only one of them is NaN then it's lambda2. Lambda is
        ///     such that ray.Start + lambda * (ray.End - ray.Start) gives the point of intersection.</summary>
        public static void RayWithRectangle(ref EdgeD ray, ref RectangleD rect, out double lambda1, out double lambda2)
        {
            double lambda, dummy;
            bool   done1 = false;

            lambda1 = lambda2 = double.NaN;

            for (int i = 0; i < 4; i++)
            {
                EdgeD segment;
                switch (i)
                {
                case 0: segment = new EdgeD(rect.Left, rect.Top, rect.Right, rect.Top); break;

                case 1: segment = new EdgeD(rect.Right, rect.Top, rect.Right, rect.Bottom); break;

                case 2: segment = new EdgeD(rect.Right, rect.Bottom, rect.Left, rect.Bottom); break;

                case 3: segment = new EdgeD(rect.Left, rect.Bottom, rect.Left, rect.Top); break;

                default: throw new InternalErrorException("fsvxhfhj");     // unreachable
                }

                Intersect.RayWithSegment(ref ray, ref segment, out lambda, out dummy);

                if (!double.IsNaN(lambda))
                {
                    if (!done1)
                    {
                        lambda1 = lambda;
                        done1   = true;
                    }
                    else if (lambda != lambda1)
                    {
                        if (lambda > lambda1)
                        {
                            lambda2 = lambda;
                        }
                        else
                        {
                            lambda2 = lambda1;
                            lambda1 = lambda;
                        }
                        return;
                    }
                }
            }
        }
예제 #5
0
파일: Intersect.cs 프로젝트: biorpg/RT.Util
        /// <summary>Returns a polygon formed by intersecting an arbitrary polygon with a convex polygon.</summary>
        public static PolygonD PolygonWithConvexPolygon(PolygonD mainPoly, PolygonD clipPoly)
        {
            if (mainPoly.Vertices.Count <= 2 || clipPoly.Vertices.Count <= 2)
            {
                throw new InvalidOperationException("One of the polygons has 2 vertices or fewer.");
            }
            var result         = new List <PointD>();
            var resultVertices = mainPoly.Vertices.ToList();

            foreach (var clipEdge in clipPoly.ToEdges())
            {
                var newVertices = new List <PointD>();
                var vertexStart = resultVertices[resultVertices.Count - 1];
                foreach (var vertexEnd in resultVertices)
                {
                    if (clipEdge.CrossZ(vertexStart) > 0)
                    {
                        if (clipEdge.CrossZ(vertexEnd) > 0)
                        {
                            newVertices.Add(vertexEnd);
                        }
                        else
                        {
                            newVertices.Add(Intersect.LineWithLine(clipEdge, new EdgeD(vertexStart, vertexEnd)));
                        }
                    }
                    else
                    {
                        if (clipEdge.CrossZ(vertexEnd) > 0)
                        {
                            newVertices.Add(Intersect.LineWithLine(clipEdge, new EdgeD(vertexStart, vertexEnd)));
                            newVertices.Add(vertexEnd);
                        }
                    }
                    vertexStart = vertexEnd;
                }
                resultVertices = newVertices;
            }
            return(new PolygonD(resultVertices));
        }
예제 #6
0
 /// <summary>Returns true if this bounding box intersects with the specified bounding box.</summary>
 public bool IntersectsWithBoundingBox(BoundingBoxD box)
 {
     return(Intersect.BoundingBoxWithBoundingBox(ref this, ref box));
 }
예제 #7
0
 /// <summary>Returns true if this bounding box intersects with the specified ray.</summary>
 public bool IntersectsWithRay(EdgeD ray)
 {
     return(Intersect.RayWithBoundingBox(ref ray, ref this));
 }