public static void TriangleLineRelations(
     Vector2d origin, Vector2d direction,
     Triangle2d tri, ref Vector3d dist, ref Vector3i sign,
     ref int positive, ref int negative, ref int zero)
 {
     positive = 0;
     negative = 0;
     zero     = 0;
     for (int i = 0; i < 3; ++i)
     {
         Vector2d diff = tri[i] - origin;
         dist[i] = diff.DotPerp(direction);
         if (dist[i] > MathUtil.ZeroTolerance)
         {
             sign[i] = 1;
             ++positive;
         }
         else if (dist[i] < -MathUtil.ZeroTolerance)
         {
             sign[i] = -1;
             ++negative;
         }
         else
         {
             dist[i] = 0.0;
             sign[i] = 0;
             ++zero;
         }
     }
 }
Example #2
0
        public static IntersectionType Classify(Vector2d P0, Vector2d D0, Vector2d P1, Vector2d D1,
                                                double dotThreshold, ref Vector2d s)
        {
            // Ensure dotThreshold is nonnegative.
            dotThreshold = Math.Max(dotThreshold, (double)0);

            // The intersection of two lines is a solution to P0+s0*D0 = P1+s1*D1.
            // Rewrite this as s0*D0 - s1*D1 = P1 - P0 = Q.  If D0.Dot(Perp(D1)) = 0,
            // the lines are parallel.  Additionally, if Q.Dot(Perp(D1)) = 0, the
            // lines are the same.  If D0.Dot(Perp(D1)) is not zero, then
            //   s0 = Q.Dot(Perp(D1))/D0.Dot(Perp(D1))
            // produces the point of intersection.  Also,
            //   s1 = Q.Dot(Perp(D0))/D0.Dot(Perp(D1))

            Vector2d diff        = P1 - P0;
            double   D0DotPerpD1 = D0.DotPerp(D1);

            if (Math.Abs(D0DotPerpD1) > dotThreshold)
            {
                // Lines intersect in a single point.
                double invD0DotPerpD1 = ((double)1) / D0DotPerpD1;
                double diffDotPerpD0  = diff.DotPerp(D0);
                double diffDotPerpD1  = diff.DotPerp(D1);
                s[0] = diffDotPerpD1 * invD0DotPerpD1;
                s[1] = diffDotPerpD0 * invD0DotPerpD1;
                return(IntersectionType.Point);
            }

            // Lines are parallel.
            diff.Normalize();
            double diffNDotPerpD1 = diff.DotPerp(D1);

            if (Math.Abs(diffNDotPerpD1) <= dotThreshold)
            {
                // Lines are colinear.
                return(IntersectionType.Line);
            }

            // Lines are parallel, but distinct.
            return(IntersectionType.Empty);
        }
Example #3
0
        /// <summary>
        /// Test if segments intersect. Returns true for parallel-line overlaps.
        /// Returns same result as IntrSegment2Segment2.
        /// </summary>
        public bool Intersects(ref Segment2d seg2, double dotThresh = double.Epsilon, double intervalThresh = 0)
        {
            // see IntrLine2Line2 and IntrSegment2Segment2 for details on this code

            Vector2d diff        = seg2.Center - Center;
            double   D0DotPerpD1 = Direction.DotPerp(seg2.Direction);

            if (Math.Abs(D0DotPerpD1) > dotThresh)
            {               // Lines intersect in a single point.
                double invD0DotPerpD1 = ((double)1) / D0DotPerpD1;
                double diffDotPerpD0  = diff.DotPerp(Direction);
                double diffDotPerpD1  = diff.DotPerp(seg2.Direction);
                double s  = diffDotPerpD1 * invD0DotPerpD1;
                double s2 = diffDotPerpD0 * invD0DotPerpD1;
                return(Math.Abs(s) <= (Extent + intervalThresh) &&
                       Math.Abs(s2) <= (seg2.Extent + intervalThresh));
            }

            // Lines are parallel.
            diff.Normalize();
            double diffNDotPerpD1 = diff.DotPerp(seg2.Direction);

            if (Math.Abs(diffNDotPerpD1) <= dotThresh)
            {
                // Compute the location of segment1 endpoints relative to segment0.
                diff = seg2.Center - Center;
                double t1      = Direction.Dot(diff);
                double tmin    = t1 - seg2.Extent;
                double tmax    = t1 + seg2.Extent;
                var    extents = new Interval1d(-Extent, Extent);
                if (extents.Overlaps(new Interval1d(tmin, tmax)))
                {
                    return(true);
                }

                return(false);
            }

            // lines are parallel but not collinear
            return(false);
        }
Example #4
0
        /// <summary>
        /// Calculate intersection point between this line and another one.
        /// Returns Vector2d.MaxValue if lines are parallel.
        /// </summary>
        /// <returns></returns>
        public Vector2d IntersectionPoint(ref Line2d other, double dotThresh = MathUtil.ZeroTolerance)
        {
            // see IntrLine2Line2 for explanation of algorithm
            Vector2d diff        = other.Origin - Origin;
            double   D0DotPerpD1 = Direction.DotPerp(other.Direction);

            if (Math.Abs(D0DotPerpD1) > dotThresh)                      // Lines intersect in a single point.
            {
                double invD0DotPerpD1 = ((double)1) / D0DotPerpD1;
                double diffDotPerpD1  = diff.DotPerp(other.Direction);
                double s = diffDotPerpD1 * invD0DotPerpD1;
                return(Origin + s * Direction);
            }
            // Lines are parallel.
            return(Vector2d.MaxValue);
        }
Example #5
0
        public double GetCurvature(double t)
        {
            Vector2d der1     = GetFirstDerivative(t);
            Vector2d der2     = GetSecondDerivative(t);
            double   speedSqr = der1.LengthSquared;

            if (speedSqr >= MathUtil.ZeroTolerance)
            {
                double numer = der1.DotPerp(der2);
                double denom = Math.Pow(speedSqr, (double)1.5);
                return(numer / denom);
            }
            else
            {
                // Curvature is indeterminate, just return 0.
                return((double)0);
            }
        }
        bool GetCoplanarIntersection(ref Plane3d plane, ref Triangle3d tri0, ref Triangle3d tri1)
        {
            // Project triangles onto coordinate plane most aligned with plane
            // normal.
            int    maxNormal = 0;
            double fmax      = Math.Abs(plane.Normal.x);
            double absMax    = Math.Abs(plane.Normal.y);

            if (absMax > fmax)
            {
                maxNormal = 1;
                fmax      = absMax;
            }
            absMax = Math.Abs(plane.Normal.z);
            if (absMax > fmax)
            {
                maxNormal = 2;
            }

            Triangle2d projTri0 = new Triangle2d(), projTri1 = new Triangle2d();
            int        i;

            if (maxNormal == 0)
            {
                // Project onto yz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].yz;
                    projTri1[i] = tri1[i].yz;
                }
            }
            else if (maxNormal == 1)
            {
                // Project onto xz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xz;
                    projTri1[i] = tri1[i].xz;
                }
            }
            else
            {
                // Project onto xy-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xy;
                    projTri1[i] = tri1[i].xy;
                }
            }

            // 2D triangle intersection routines require counterclockwise ordering.
            Vector2d save;
            Vector2d edge0 = projTri0[1] - projTri0[0];
            Vector2d edge1 = projTri0[2] - projTri0[0];

            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri0[1];
                projTri0[1] = projTri0[2];
                projTri0[2] = save;
            }

            edge0 = projTri1[1] - projTri1[0];
            edge1 = projTri1[2] - projTri1[0];
            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri1[1];
                projTri1[1] = projTri1[2];
                projTri1[2] = save;
            }

            IntrTriangle2Triangle2 intr = new IntrTriangle2Triangle2(projTri0, projTri1);

            if (!intr.Find())
            {
                return(false);
            }

            PolygonPoints = new Vector3d[intr.Quantity];

            // Map 2D intersections back to the 3D triangle space.
            Quantity = intr.Quantity;
            if (maxNormal == 0)
            {
                double invNX = ((double)1) / plane.Normal.x;
                for (i = 0; i < Quantity; i++)
                {
                    double y = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3d(x, y, z);
                }
            }
            else if (maxNormal == 1)
            {
                double invNY = ((double)1) / plane.Normal.y;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3d(x, y, z);
                }
            }
            else
            {
                double invNZ = ((double)1) / plane.Normal.z;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double y = intr.Points[i].y;
                    double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y);
                    PolygonPoints[i] = new Vector3d(x, y, z);
                }
            }

            Result = IntersectionResult.Intersects;
            Type   = IntersectionType.Polygon;
            return(true);
        }