Пример #1
0
        /// <summary>
        /// Point on the perpendicular to the line
        /// </summary>
        public Point3d PerpendicularTo(Line3d l)
        {
            Vector3d r1 = this.Point.ToVector;
            Vector3d r2 = l.Point.ToVector;
            Vector3d s1 = this.Direction;
            Vector3d s2 = l.Direction;

            if (s1.Cross(s2).Norm > GeometRi3D.Tolerance)
            {
                Point3d p = l.PerpendicularTo(new Line3d(this.Point, this.Direction));
                if (p.BelongsTo(this))
                {
                    r1 = r2 + (r2 - r1) * s1.Cross(s1.Cross(s2)) / (s1 * s2.Cross(s1.Cross(s2))) * s2;
                    return(r1.ToPoint);
                }
                else
                {
                    return(this.Point.ProjectionTo(l));
                }
            }
            else
            {
                throw new Exception("Lines are parallel");
            }
        }
Пример #2
0
        /// <summary>
        /// Shortest distance to a line
        /// </summary>
        public double DistanceTo(Line3d l)
        {
            Vector3d r1 = this.Point.ToVector;
            Vector3d r2 = l.Point.ToVector;
            Vector3d s1 = this.Direction;
            Vector3d s2 = l.Direction;

            if (s1.Cross(s2).Norm > GeometRi3D.Tolerance)
            {
                // Crossing lines
                Point3d p = l.PerpendicularTo(new Line3d(this.Point, this.Direction));
                if (p.BelongsTo(this))
                {
                    return(Abs((r2 - r1) * s1.Cross(s2)) / s1.Cross(s2).Norm);
                }
                else
                {
                    return(this.Point.DistanceTo(l));
                }
            }
            else
            {
                // Parallel lines
                return((r2 - r1).Cross(s1).Norm / s1.Norm);
            }
        }
Пример #3
0
 /// <summary>
 /// Returns shortest distance from segment to the line
 /// </summary>
 public double DistanceTo(Line3d l)
 {
     if (l.PerpendicularTo(this.ToLine).BelongsTo(this))
     {
         return(l.DistanceTo(this.ToLine));
     }
     else
     {
         return(Min(this.P1.DistanceTo(l), this.P2.DistanceTo(l)));
     }
 }
Пример #4
0
        /// <summary>
        /// Get intersection of line with other line.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Line3d'.
        /// </summary>
        public object IntersectionWith(Line3d l)
        {
            if (l.IsParallelTo(this) && l.Point.BelongsTo(this))
            {
                return(this.Copy());
            }

            Point3d p = l.PerpendicularTo(this);

            if (p.BelongsTo(l))
            {
                return(p);
            }
            else
            {
                return(null);
            }
        }
Пример #5
0
        /// <summary>
        /// Get intersection of segment with line.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Line3d l)
        {
            if (this.BelongsTo(l))
            {
                return(this.Copy());
            }

            Point3d p = l.PerpendicularTo(this.ToLine);

            if (p.BelongsTo(this) && p.BelongsTo(l))
            {
                return(p);
            }
            else
            {
                return(null);
            }
        }
Пример #6
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);
                }
            }
        }