Beispiel #1
0
 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)));
     }
 }
Beispiel #2
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));
        }
Beispiel #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);

            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));
        }
Beispiel #4
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);
            }
        }
Beispiel #5
0
 /// <summary>
 /// Shortest distance between line and segment
 /// </summary>
 public double DistanceTo(Segment3d s)
 {
     return(s.DistanceTo(this));
 }
Beispiel #6
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);
        }