Exemplo n.º 1
0
        /// <summary>
        /// Shortest distance between triangle and point
        /// </summary>
        public double DistanceTo(Point3d p)
        {
            Point3d projection_point = p.ProjectionTo(this.ToPlane);

            double tol  = GeometRi3D.Tolerance;
            bool   mode = GeometRi3D.UseAbsoluteTolerance;

            GeometRi3D.Tolerance            = GeometRi3D.DefaultTolerance;
            GeometRi3D.UseAbsoluteTolerance = true;

            int code = _PointLocation(projection_point);

            // Restore initial state
            GeometRi3D.UseAbsoluteTolerance = mode;
            GeometRi3D.Tolerance            = tol;

            if (code >= 0)
            {
                return(p.DistanceTo(projection_point));
            }

            Segment3d AB = new Segment3d(this._a, this._b);
            Segment3d BC = new Segment3d(this._b, this._c);
            Segment3d AC = new Segment3d(this._a, this._c);

            double dist  = p.DistanceTo(AB);
            double dist2 = p.DistanceTo(BC);
            double dist3 = p.DistanceTo(AC);

            return(Min(dist, Min(dist2, dist3)));
        }
Exemplo n.º 2
0
 /// <summary>
 /// Shortest distance between sphere and segment
 /// </summary>
 public double DistanceTo(Segment3d s)
 {
     if (this.Center.ProjectionTo(s.ToLine).BelongsTo(s))
     {
         return(this.DistanceTo(s.ToLine));
     }
     else
     {
         return(Min(this.DistanceTo(s.P1), this.DistanceTo(s.P2)));
     }
 }
Exemplo n.º 3
0
 /// <summary>
 /// Return Axis Aligned Bounding Box (AABB) in given coordinate system.
 /// </summary>
 public Box3d BoundingBox(Coord3d coord = null)
 {
     coord = (coord == null) ? Coord3d.GlobalCS : coord;
     Line3d l1 = new Line3d(coord.Origin, coord.Xaxis);
     Line3d l2 = new Line3d(coord.Origin, coord.Yaxis);
     Line3d l3 = new Line3d(coord.Origin, coord.Zaxis);
     Segment3d s1 = this.ProjectionTo(l1);
     Segment3d s2 = this.ProjectionTo(l2);
     Segment3d s3 = this.ProjectionTo(l3);
     return new Box3d(_point, s1.Length, s2.Length, s3.Length, coord);
 }
Exemplo n.º 4
0
        /// <summary>
        /// Returns shortest distance from point to the segment
        /// </summary>
        public double DistanceTo(Segment3d s)
        {
            Point3d projection = this.ProjectionTo(s.ToLine);

            if (s._AxialPointLocation(projection) > 0)
            {
                return(this.DistanceTo(projection));
            }
            else
            {
                return(Min(this.DistanceTo(s.P1), this.DistanceTo(s.P2)));
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Calculates the point on the triangle closest to given point.
        /// </summary>
        public Point3d ClosestPoint(Point3d p)
        {
            Point3d projection_point = p.ProjectionTo(this.ToPlane);

            double tol  = GeometRi3D.Tolerance;
            bool   mode = GeometRi3D.UseAbsoluteTolerance;

            GeometRi3D.Tolerance            = GeometRi3D.DefaultTolerance;
            GeometRi3D.UseAbsoluteTolerance = true;

            int code = _PointLocation(projection_point);

            // Restore initial state
            GeometRi3D.UseAbsoluteTolerance = mode;
            GeometRi3D.Tolerance            = tol;

            if (code >= 0)
            {
                return(projection_point);
            }

            Segment3d AB = new Segment3d(this._a, this._b);
            Segment3d BC = new Segment3d(this._b, this._c);
            Segment3d AC = new Segment3d(this._a, this._c);

            double  dist          = p.DistanceTo(AB);
            Point3d closest_point = AB.ClosestPoint(p);
            double  dist2         = p.DistanceTo(BC);

            if (dist2 < dist)
            {
                dist          = dist2;
                closest_point = BC.ClosestPoint(p);
            }
            dist2 = p.DistanceTo(AC);
            if (dist2 < dist)
            {
                dist          = dist2;
                closest_point = AC.ClosestPoint(p);
            }

            return(closest_point);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Return Axis Aligned Bounding Box (AABB) in given coordinate system.
        /// </summary>
        public Box3d BoundingBox(Coord3d coord = null)
        {
            coord = (coord == null) ? Coord3d.GlobalCS : coord;
            Line3d l1 = new Line3d(coord.Origin, coord.Xaxis);
            Line3d l2 = new Line3d(coord.Origin, coord.Yaxis);
            Line3d l3 = new Line3d(coord.Origin, coord.Zaxis);

            double    px, py, pz, lx, ly, lz;
            Segment3d s = this.ProjectionTo(l1);

            px = (0.5 * (s.P1 + s.P2)).ConvertTo(coord).X;
            lx = s.Length;
            s  = this.ProjectionTo(l2);
            py = (0.5 * (s.P1 + s.P2)).ConvertTo(coord).Y;
            ly = s.Length;
            s  = this.ProjectionTo(l3);
            pz = (0.5 * (s.P1 + s.P2)).ConvertTo(coord).Z;
            lz = s.Length;

            return(new Box3d(new Point3d(px, py, pz, coord), lx, ly, lz, coord));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Get intersection of segment with triangle.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Segment3d s)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * Max(s.Length, Max(AB, Max(BC, AC)));
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(s);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

            object obj = this.IntersectionWith(s.ToLine);

            if (obj == null)
            {
                return(null);
            }
            else if (obj.GetType() == typeof(Point3d))
            {
                Point3d p = (Point3d)obj;
                if (p.BelongsTo(s))
                {
                    return(p);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                return(s.IntersectionWith((Segment3d)obj));
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Determines whether two objects are equal.
        /// </summary>
        public override bool Equals(object obj)
        {
            if (obj == null || (!object.ReferenceEquals(this.GetType(), obj.GetType())))
            {
                return(false);
            }
            Segment3d s = (Segment3d)obj;

            if (GeometRi3D.UseAbsoluteTolerance)
            {
                return((this.P1 == s.P1 && this.P2 == s.P2) | (this.P1 == s.P2 && this.P2 == s.P1));
            }
            else
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * this.Length;
                GeometRi3D.UseAbsoluteTolerance = true;
                bool result = (this.P1 == s.P1 && this.P2 == s.P2) | (this.P1 == s.P2 && this.P2 == s.P1);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Intersection of circle with segment.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Segment3d s)
        {
            Ellipse e = this.ToEllipse;

            return(e.IntersectionWith(s));
        }
Exemplo n.º 10
0
        /// <summary>
        /// Get intersection of ray with segment.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Segment3d s)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * s.Length;
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(s);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

            object obj = this.ToLine.IntersectionWith(s);

            if (obj == null)
            {
                return(null);
            }
            else if (obj.GetType() == typeof(Point3d))
            {
                Point3d p = (Point3d)obj;
                if (p.BelongsTo(this))
                {
                    return(p);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                Segment3d intersection = (Segment3d)obj;
                if (intersection.P1.BelongsTo(this) && intersection.P2.BelongsTo(this))
                {
                    return(intersection);
                }
                else if (intersection.P1.BelongsTo(this))
                {
                    if (intersection.P1 == this.Point)
                    {
                        return(this.Point);
                    }
                    else
                    {
                        return(new Segment3d(this.Point, intersection.P1));
                    }
                }
                else if (intersection.P2.BelongsTo(this))
                {
                    if (intersection.P2 == this.Point)
                    {
                        return(this.Point);
                    }
                    else
                    {
                        return(new Segment3d(this.Point, intersection.P2));
                    }
                }
                else
                {
                    return(null);
                }
            }
        }
Exemplo n.º 11
0
 /// <summary>
 /// Distance to a segment
 /// </summary>
 public double DistanceTo(Segment3d s)
 {
     return(s.DistanceTo(this));
 }
Exemplo n.º 12
0
        /// <summary>
        /// Get intersection of line with triangle.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Line3d l)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * Max(AB, Max(BC, AC));
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(l);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

            Plane3d s = new Plane3d(this.A, this.Normal);

            object obj = l.IntersectionWith(s);

            if (obj == null)
            {
                return(null);
            }
            else
            {
                if (obj.GetType() == typeof(Line3d))
                {
                    Segment3d sAB = new Segment3d(A, B);
                    Segment3d sBC = new Segment3d(B, C);
                    Segment3d sAC = new Segment3d(A, C);

                    // Line coincides with one side, return segment
                    if (sAB.BelongsTo(l))
                    {
                        return(sAB);
                    }
                    if (sBC.BelongsTo(l))
                    {
                        return(sBC);
                    }
                    if (sAC.BelongsTo(l))
                    {
                        return(sAC);
                    }

                    Point3d pAB = (Point3d)sAB.IntersectionWith(l);
                    Point3d pBC = (Point3d)sBC.IntersectionWith(l);
                    Point3d pAC = (Point3d)sAC.IntersectionWith(l);

                    bool bAB = (object.ReferenceEquals(null, pAB)) ? false : pAB.BelongsTo(sAB);
                    bool bAC = (object.ReferenceEquals(null, pAC)) ? false : pAC.BelongsTo(sAC);
                    bool bBC = (object.ReferenceEquals(null, pBC)) ? false : pBC.BelongsTo(sBC);

                    // Line crosses one corner, return point
                    if (bAB && bBC && pAB == pBC && !bAC)
                    {
                        return(pAB);
                    }
                    if (bAB && bAC && pAB == pAC && !bBC)
                    {
                        return(pAB);
                    }
                    if (bAC && bBC && pAC == pBC && !bAB)
                    {
                        return(pAC);
                    }

                    // Line crosses two sides, return segment
                    if (bAB && bBC && !bAC)
                    {
                        return(new Segment3d(pAB, pBC));
                    }
                    if (bAB && bAC && !bBC)
                    {
                        return(new Segment3d(pAB, pAC));
                    }
                    if (bAC && bBC && !bAB)
                    {
                        return(new Segment3d(pAC, pBC));
                    }

                    // Line crosses one corner and one side, return segment
                    if (pAB == pBC && bAC)
                    {
                        return(new Segment3d(pAB, pAC));
                    }
                    if (pAB == pAC && bBC)
                    {
                        return(new Segment3d(pAB, pBC));
                    }
                    if (pAC == pBC && bAB)
                    {
                        return(new Segment3d(pAB, pAC));
                    }

                    //else
                    return(null);
                }
                else
                {
                    // result of intersection is point
                    Point3d p = (Point3d)obj;
                    if (p.BelongsTo(this))
                    {
                        return(p);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Returns shortest distance between two segments
        /// </summary>
        public double DistanceTo(Segment3d s)
        {
            // Algorithm by Dan Sunday
            // http://geomalgorithms.com/a07-_distance.html

            double small = GeometRi3D.Tolerance;


            Vector3d u = this.ToVector;
            Vector3d v = s.ToVector;
            Vector3d w = new Vector3d(s.P1, this.P1);

            double a = u * u;
            double b = u * v;
            double c = v * v;
            double d = u * w;
            double e = v * w;

            double DD = a * c - b * b;
            double sc = 0;
            double sN = 0;
            double sD = 0;
            double tc = 0;
            double tN = 0;
            double tD = 0;

            sD = DD;
            tD = DD;

            if (DD < small)
            {
                // the lines are almost parallel, force using point Me.P1 to prevent possible division by 0.0 later
                sN = 0.0;
                sD = 1.0;
                tN = e;
                tD = c;
            }
            else
            {
                // get the closest points on the infinite lines
                sN = (b * e - c * d);
                tN = (a * e - b * d);
                if ((sN < 0.0))
                {
                    // sc < 0 => the s=0 edge Is visible
                    sN = 0.0;
                    tN = e;
                    tD = c;
                }
                else if ((sN > sD))
                {
                    // sc > 1  => the s=1 edge Is visible
                    sN = sD;
                    tN = e + b;
                    tD = c;
                }
            }

            if ((tN < 0.0))
            {
                // tc < 0 => the t=0 edge Is visible
                tN = 0.0;
                // recompute sc for this edge
                if ((-d < 0.0))
                {
                    sN = 0.0;
                }
                else if ((-d > a))
                {
                    sN = sD;
                }
                else
                {
                    sN = -d;
                    sD = a;
                }
            }
            else if ((tN > tD))
            {
                // tc > 1  => the t=1 edge Is visible
                tN = tD;
                // recompute sc for this edge
                if (((-d + b) < 0.0))
                {
                    sN = 0;
                }
                else if (((-d + b) > a))
                {
                    sN = sD;
                }
                else
                {
                    sN = (-d + b);
                    sD = a;
                }
            }

            // finally do the division to get sc And tc
            sc = Abs(sN) < small ? 0.0 : sN / sD;
            tc = Abs(tN) < small ? 0.0 : tN / tD;

            // get the difference of the two closest points
            Vector3d dP = w + (sc * u) - (tc * v);

            // =  S1(sc) - S2(tc)

            return(dP.Norm);
        }
Exemplo n.º 14
0
 /// <summary>
 /// Check if point belongs to the segment
 /// </summary>
 /// <returns>True, if the point belongs to the segment</returns>
 public bool BelongsTo(Segment3d s)
 {
     return(this.BelongsTo(s.ToRay) && this.BelongsTo(new Ray3d(s.P2, new Vector3d(s.P2, s.P1))));
 }
Exemplo n.º 15
0
        /// <summary>
        /// Get intersection of line with triangle.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Line3d l)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * Max(AB, Max(BC, AC));
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(l);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

            Plane3d s = new Plane3d(this.A, this.Normal);

            object obj = l.IntersectionWith(s);

            if (obj == null)
            {
                return(null);
            }
            else
            {
                if (obj.GetType() == typeof(Line3d))
                {
                    // Coplanar line and triangle

                    // Check intersection in one corner
                    // or in corner and opposite side
                    if (_a.BelongsTo(l))
                    {
                        object obj2 = new Segment3d(_b, _c).IntersectionWith(l);
                        if (obj2 != null && obj2.GetType() == typeof(Point3d))
                        {
                            return(new Segment3d(_a, (Point3d)obj2));
                        }
                        else
                        {
                            return(A);
                        }
                    }

                    if (_b.BelongsTo(l))
                    {
                        object obj2 = new Segment3d(_a, _c).IntersectionWith(l);
                        if (obj2 != null && obj2.GetType() == typeof(Point3d))
                        {
                            return(new Segment3d(_b, (Point3d)obj2));
                        }
                        else
                        {
                            return(B);
                        }
                    }

                    if (_c.BelongsTo(l))
                    {
                        object obj2 = new Segment3d(_a, _b).IntersectionWith(l);
                        if (obj2 != null && obj2.GetType() == typeof(Point3d))
                        {
                            return(new Segment3d(_c, (Point3d)obj2));
                        }
                        else
                        {
                            return(C);
                        }
                    }

                    // Check intersection with two sides
                    object objAB = new Segment3d(_a, _b).IntersectionWith(l);
                    object objBC = new Segment3d(_b, _c).IntersectionWith(l);
                    if (objAB != null && objAB.GetType() == typeof(Point3d))
                    {
                        if (objBC != null && objBC.GetType() == typeof(Point3d))
                        {
                            return(new Segment3d((Point3d)objAB, (Point3d)objBC));
                        }
                        else
                        {
                            object objAC = new Segment3d(_a, _c).IntersectionWith(l);
                            if (objAC != null && objAC.GetType() == typeof(Point3d))
                            {
                                return(new Segment3d((Point3d)objAB, (Point3d)objAC));
                            }
                            else
                            {
                                return((Point3d)objAB);
                            }
                        }
                    }

                    if (objBC != null && objBC.GetType() == typeof(Point3d))
                    {
                        object objAC = new Segment3d(_a, _c).IntersectionWith(l);
                        if (objAC != null && objAC.GetType() == typeof(Point3d))
                        {
                            return(new Segment3d((Point3d)objBC, (Point3d)objAC));
                        }
                        else
                        {
                            return((Point3d)objBC);
                        }
                    }

                    object objAC2 = new Segment3d(_a, _c).IntersectionWith(l);
                    if (objAC2 != null && objAC2.GetType() == typeof(Point3d))
                    {
                        return((Point3d)objAC2);
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    // result of intersection is point
                    Point3d p = (Point3d)obj;
                    if (p.BelongsTo(this))
                    {
                        return(p);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Get intersection of segment with other segment.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Segment3d s)
        {
            if (this == s)
            {
                return(this.Copy());
            }

            Line3d l1 = this.ToLine;
            Line3d l2 = s.ToLine;

            if (this.BelongsTo(l2) || s.BelongsTo(l1))
            {
                // Segments are collinear

                // Relative tolerance check ================================
                double tol = GeometRi3D.Tolerance;
                if (!GeometRi3D.UseAbsoluteTolerance)
                {
                    tol = GeometRi3D.Tolerance * Max(this.Length, s.Length);
                }
                //==========================================================

                // Create local CS with X-axis along segment 's'
                Vector3d v2 = s.ToVector.OrthogonalVector;
                Coord3d  cs = new Coord3d(s.P1, s.ToVector, v2);
                double   x1 = 0.0;
                double   x2 = s.Length;

                double t3 = this.P1.ConvertTo(cs).X;
                double t4 = this.P2.ConvertTo(cs).X;
                double x3 = Min(t3, t4);
                double x4 = Max(t3, t4);

                // Segments do not overlap
                if (GeometRi3D.Smaller(x4, x1, tol) || GeometRi3D.Greater(x3, x2, tol))
                {
                    return(null);
                }

                // One common point
                if (GeometRi3D.AlmostEqual(Max(x3, x4), x1, tol))
                {
                    return(new Point3d(x1, 0, 0, cs));
                }
                if (GeometRi3D.AlmostEqual(Min(x3, x4), x2, tol))
                {
                    return(new Point3d(x2, 0, 0, cs));
                }

                // Overlaping segments
                x1 = Max(x1, x3);
                x2 = Min(x2, x4);
                return(new Segment3d(new Point3d(x1, 0, 0, cs), new Point3d(x2, 0, 0, cs)));
            }
            else
            {
                Point3d p = l1.PerpendicularTo(l2);
                if (p.BelongsTo(this) && p.BelongsTo(s))
                {
                    return(p);
                }
                else
                {
                    return(null);
                }
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// Intersection of two circles.
        /// Returns 'null' (no intersection) or object of type 'Circle3d', 'Point3d' or 'Segment3d'.
        /// In 2D (coplanar circles) the segment will define two intersection points.
        /// </summary>
        public object IntersectionWith(Circle3d c)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * Max(this.R, c.R);
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(c);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

            if (this.Normal.IsParallelTo(c.Normal))
            {
                if (this.Center.BelongsTo(new Plane3d(c.Center, c.Normal)))
                {
                    // Coplanar objects
                    // Search 2D intersection of two circles

                    // Equal circles
                    if (this.Center == c.Center && GeometRi3D.AlmostEqual(this.R, c.R))
                    {
                        return(this.Copy());
                    }

                    double d = this.Center.DistanceTo(c.Center);

                    // Separated circles
                    if (GeometRi3D.Greater(d, this.R + c.R))
                    {
                        return(null);
                    }

                    // One circle inside the other
                    if (d < Abs(this.R - c.R) - GeometRi3D.Tolerance)
                    {
                        return(null);
                    }

                    // Outer tangency
                    if (GeometRi3D.AlmostEqual(d, this.R + c.R))
                    {
                        Vector3d vec = new Vector3d(this.Center, c.Center);
                        return(this.Center.Translate(this.R * vec.Normalized));
                    }

                    // Inner tangency
                    if (Abs(Abs(this.R - c.R) - d) < GeometRi3D.Tolerance)
                    {
                        Vector3d vec = new Vector3d(this.Center, c.Center);
                        if (this.R > c.R)
                        {
                            return(this.Center.Translate(this.R * vec.Normalized));
                        }
                        else
                        {
                            return(this.Center.Translate(-this.R * vec.Normalized));
                        }
                    }

                    // intersecting circles
                    // Create local CS with origin in circle's center
                    Vector3d vec1     = new Vector3d(this.Center, c.Center);
                    Vector3d vec2     = vec1.Cross(this.Normal);
                    Coord3d  local_cs = new Coord3d(this.Center, vec1, vec2);

                    double  x  = 0.5 * (d * d - c.R * c.R + this.R * this.R) / d;
                    double  y  = 0.5 * Sqrt((-d + c.R - this.R) * (-d - c.R + this.R) * (-d + c.R + this.R) * (d + c.R + this.R)) / d;
                    Point3d p1 = new Point3d(x, y, 0, local_cs);
                    Point3d p2 = new Point3d(x, -y, 0, local_cs);
                    return(new Segment3d(p1, p2));
                }
                else
                {
                    // parallel objects
                    return(null);
                }
            }
            else
            {
                // Check 3D intersection
                Plane3d plane = new Plane3d(this.Center, this.Normal);
                object  obj   = plane.IntersectionWith(c);

                if (obj == null)
                {
                    return(null);
                }
                else if (obj.GetType() == typeof(Point3d))
                {
                    Point3d p = (Point3d)obj;
                    if (p.BelongsTo(c))
                    {
                        return(p);
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    Segment3d s = (Segment3d)obj;
                    return(s.IntersectionWith(this));
                }
            }
        }
Exemplo n.º 18
0
 /// <summary>
 /// Get intersection of line with segment.
 /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
 /// </summary>
 public object IntersectionWith(Segment3d s)
 {
     return(s.IntersectionWith(this));
 }
Exemplo n.º 19
0
 /// <summary>
 /// Get intersection of segment with box.
 /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
 /// </summary>
 public object IntersectionWith(Segment3d s)
 {
     return(_line_intersection(s.ToLine, 0.0, s.Length));
 }
Exemplo n.º 20
0
        /// <summary>
        /// Get intersection of segment with other segment.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Segment3d s)
        {
            if (this == s)
            {
                return(this.Copy());
            }

            object obj = this.ToLine.IntersectionWith(s);

            if (obj == null)
            {
                return(null);
            }

            if (obj.GetType() == typeof(Point3d))
            {
                Point3d p = (Point3d)obj;
                if (p.BelongsTo(this) && p.BelongsTo(s))
                {
                    return(p);
                }
                else
                {
                    return(null);
                }
            }
            else if (obj.GetType() == typeof(Segment3d))
            {
                // Segments are collinear

                // Relative tolerance check ================================
                double tol = GeometRi3D.Tolerance;
                if (!GeometRi3D.UseAbsoluteTolerance)
                {
                    tol = GeometRi3D.Tolerance * Max(this.Length, s.Length);
                }
                //==========================================================

                // Create local CS with X-axis along segment 's'
                Vector3d v2 = s.ToVector.OrthogonalVector;
                Coord3d  cs = new Coord3d(s.P1, s.ToVector, v2);
                double   x1 = 0.0;
                double   x2 = s.Length;

                double x3 = this.P1.ConvertTo(cs).X;
                double x4 = this.P2.ConvertTo(cs).X;



                if (GeometRi3D.Smaller(Max(x3, x4), x1, tol) || GeometRi3D.Greater(Min(x3, x4), x2, tol))
                {
                    return(null);
                }

                if (GeometRi3D.AlmostEqual(Max(x3, x4), x1, tol))
                {
                    return(new Point3d(x1, 0, 0, cs));
                }
                if (GeometRi3D.AlmostEqual(Min(x3, x4), x2, tol))
                {
                    return(new Point3d(x2, 0, 0, cs));
                }

                if (GeometRi3D.Smaller(Min(x3, x4), x1, tol) && GeometRi3D.Greater(Max(x3, x4), x2, tol))
                {
                    return(s.Copy());
                }

                if (GeometRi3D.Greater(Min(x3, x4), x1, tol) && GeometRi3D.Smaller(Max(x3, x4), x2, tol))
                {
                    return(this.Copy());
                }

                if (GeometRi3D.Smaller(Min(x3, x4), x1, tol))
                {
                    return(new Segment3d(new Point3d(x1, 0, 0, cs), new Point3d(Max(x3, x4), 0, 0, cs)));
                }

                if (GeometRi3D.Greater(Max(x3, x4), x2, tol))
                {
                    return(new Segment3d(new Point3d(x2, 0, 0, cs), new Point3d(Min(x3, x4), 0, 0, cs)));
                }

                return(null);
            }
            else
            {
                return(null);
            }
        }