Exemplo n.º 1
0
        /// <summary>
        /// Get intersection of ray with plane.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Ray3d'.
        /// </summary>
        public object IntersectionWith(Plane3d s)
        {
            Vector3d r1 = this.Point.ToVector;
            Vector3d s1 = this.Direction;
            Vector3d n2 = s.Normal;

            if (Abs(s1 * n2) < GeometRi3D.Tolerance)
            {
                // Ray and plane are parallel
                if (this.Point.BelongsTo(s))
                {
                    // Ray lies in the plane
                    return(this);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                // Intersection point
                s.SetCoord(r1.Coord);
                r1 = r1 - ((r1 * n2) + s.D) / (s1 * n2) * s1;
                if (r1.ToPoint.BelongsTo(this))
                {
                    return(r1.ToPoint);
                }
                else
                {
                    return(null);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Get intersection of plane with sphere.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Circle3d'.
        /// </summary>
        public object IntersectionWith(Plane3d s)
        {
            s.SetCoord(this.Center.Coord);
            double d1 = s.A * this.X + s.B * this.Y + s.C * this.Z + s.D;
            double d2 = Math.Pow(s.A, 2) + Math.Pow(s.B, 2) + Math.Pow(s.C, 2);
            double d  = Abs(d1) / Sqrt(d2);

            if (d > this.R + GeometRi3D.Tolerance)
            {
                return(null);
            }
            else
            {
                double Xc = this.X - s.A * d1 / d2;
                double Yc = this.Y - s.B * d1 / d2;
                double Zc = this.Z - s.C * d1 / d2;

                if (Abs(d - this.R) < GeometRi3D.Tolerance)
                {
                    return(new Point3d(Xc, Yc, Zc, this.Center.Coord));
                }
                else
                {
                    double R = Sqrt(Math.Pow(this.R, 2) - Math.Pow(d, 2));
                    return(new Circle3d(new Point3d(Xc, Yc, Zc, this.Center.Coord), R, s.Normal));
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns orthogonal projection of the point to the plane
        /// </summary>
        public Point3d ProjectionTo(Plane3d s)
        {
            Vector3d r0 = new Vector3d(this, _coord);

            s.SetCoord(this.Coord);
            Vector3d n = new Vector3d(s.A, s.B, s.C, _coord);

            r0 = r0 - (r0 * n + s.D) / (n * n) * n;
            return(r0.ToPoint);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Finds the common intersection of three planes.
        /// Return 'null' (no common intersection) or object of type 'Point3d', 'Line3d' or 'Plane3d'
        /// </summary>
        public object IntersectionWith(Plane3d s2, Plane3d s3)
        {
            // Set all planes to global CS
            this.SetCoord(Coord3d.GlobalCS);
            s2.SetCoord(Coord3d.GlobalCS);
            s3.SetCoord(Coord3d.GlobalCS);
            double det = new Matrix3d(new[] { A, B, C }, new[] { s2.A, s2.B, s2.C }, new [] { s3.A, s3.B, s3.C }).Det;

            //if (Abs(det) < GeometRi3D.Tolerance)
            if (Abs(det) < 1e-12)
            {
                if (this.Normal.IsParallelTo(s2.Normal) && this.Normal.IsParallelTo(s3.Normal))
                {
                    // Planes are coplanar
                    if (this.Point.BelongsTo(s2) && this.Point.BelongsTo(s3))
                    {
                        return(this);
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (this.Normal.IsNotParallelTo(s2.Normal) && this.Normal.IsNotParallelTo(s3.Normal))
                {
                    // Planes are not parallel
                    // Find the intersection (Me,s2) and (Me,s3) and check if it is the same line
                    Line3d l1 = (Line3d)this.IntersectionWith(s2);
                    Line3d l2 = (Line3d)this.IntersectionWith(s3);
                    if (l1 == l2)
                    {
                        return(l1);
                    }
                    else
                    {
                        return(null);
                    }
                }

                // Two planes are parallel, third plane is not
                return(null);
            }
            else
            {
                double x = -new Matrix3d(new[] { D, B, C }, new[] { s2.D, s2.B, s2.C }, new[] { s3.D, s3.B, s3.C }).Det / det;
                double y = -new Matrix3d(new[] { A, D, C }, new[] { s2.A, s2.D, s2.C }, new[] { s3.A, s3.D, s3.C }).Det / det;
                double z = -new Matrix3d(new[] { A, B, D }, new[] { s2.A, s2.B, s2.D }, new[] { s3.A, s3.B, s3.D }).Det / det;
                return(new Point3d(x, y, z));
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// <para>Test if point is located in the epsilon neighborhood of the plane.</para>
 /// <para>Epsilon neighborhood is defined by a GeometRi3D.Tolerance property.</para>
 /// </summary>
 public bool BelongsTo(Plane3d s)
 {
     s.SetCoord(this.Coord);
     if (GeometRi3D.UseAbsoluteTolerance)
     {
         return(Abs(s.A * X + s.B * Y + s.C * Z + s.D) / Sqrt(s.A * s.A + s.B * s.B + s.C * s.C) < GeometRi3D.Tolerance);
     }
     else
     {
         double d = this.DistanceTo(this._coord.Origin);
         if (d > 0.0)
         {
             return(Abs(s.A * X + s.B * Y + s.C * Z + s.D) / Sqrt(s.A * s.A + s.B * s.B + s.C * s.C) / d < GeometRi3D.Tolerance);
         }
         else
         {
             return(Abs(s.A * X + s.B * Y + s.C * Z + s.D) / Sqrt(s.A * s.A + s.B * s.B + s.C * s.C) < GeometRi3D.Tolerance);
         }
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// Get intersection of plane with sphere.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Circle3d'.
        /// </summary>
        public object IntersectionWith(Plane3d s)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * this.R;
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(s);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

            s.SetCoord(this.Center.Coord);
            double d1 = s.A * this.X + s.B * this.Y + s.C * this.Z + s.D;
            double d2 = Math.Pow(s.A, 2) + Math.Pow(s.B, 2) + Math.Pow(s.C, 2);
            double d  = Abs(d1) / Sqrt(d2);

            if (d > this.R + GeometRi3D.Tolerance)
            {
                return(null);
            }
            else
            {
                double Xc = this.X - s.A * d1 / d2;
                double Yc = this.Y - s.B * d1 / d2;
                double Zc = this.Z - s.C * d1 / d2;

                if (Abs(d - this.R) < GeometRi3D.Tolerance)
                {
                    return(new Point3d(Xc, Yc, Zc, this.Center.Coord));
                }
                else
                {
                    double R = Sqrt(Math.Pow(this.R, 2) - Math.Pow(d, 2));
                    return(new Circle3d(new Point3d(Xc, Yc, Zc, this.Center.Coord), R, s.Normal));
                }
            }
        }
Exemplo n.º 7
0
 /// <summary>
 /// Returns shortest distance from point to the plane
 /// </summary>
 public double DistanceTo(Plane3d s)
 {
     s.SetCoord(this.Coord);
     return(Abs(X * s.A + Y * s.B + Z * s.C + s.D) / Sqrt(s.A * s.A + s.B * s.B + s.C * s.C));
 }
Exemplo n.º 8
0
        /// <summary>
        /// Intersection of ellipsoid with plane.
        /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Ellipse'.
        /// </summary>
        public object IntersectionWith(Plane3d plane)
        {
            // Solution 1:
            // Peter Paul Klein
            // On the Ellipsoid and Plane Intersection Equation
            // Applied Mathematics, 2012, 3, 1634-1640 (DOI:10.4236/am.2012.311226)

            // Solution 2:
            // Sebahattin Bektas
            // Intersection of an Ellipsoid and a Plane
            // International Journal of Research in Engineering and Applied Sciences, VOLUME 6, ISSUE 6 (June, 2016)

            Coord3d lc = new Coord3d(_point, _v1, _v2, "LC1");

            plane.SetCoord(lc);
            double Ax, Ay, Az, Ad;
            double a, b, c;

            if (Abs(plane.C) >= Abs(plane.A) && Abs(plane.C) >= Abs(plane.B))
            {
                a = this.A; b = this.B; c = this.C;
            }
            else
            {
                lc = new Coord3d(_point, _v2, _v3, "LC2");
                plane.SetCoord(lc);
                if (Abs(plane.C) >= Abs(plane.A) && Abs(plane.C) >= Abs(plane.B))
                {
                    a = this.B; b = this.C; c = this.A;
                }
                else
                {
                    lc = new Coord3d(_point, _v3, _v1, "LC3");
                    plane.SetCoord(lc);
                    a = this.C; b = this.A; c = this.B;
                }
            }

            Ax = plane.A; Ay = plane.B; Az = plane.C; Ad = plane.D;
            double tmp = (Az * Az * c * c);
            double AA  = 1.0 / (a * a) + Ax * Ax / tmp;
            double BB  = 2.0 * Ax * Ay / tmp;
            double CC  = 1.0 / (b * b) + Ay * Ay / tmp;
            double DD  = 2.0 * Ax * Ad / tmp;
            double EE  = 2.0 * Ay * Ad / tmp;
            double FF  = Ad * Ad / tmp - 1.0;

            double det = 4.0 * AA * CC - BB * BB;

            if (GeometRi3D.AlmostEqual(det, 0))
            {
                return(null);
            }
            double X0 = (BB * EE - 2 * CC * DD) / det;
            double Y0 = (BB * DD - 2 * AA * EE) / det;
            double Z0 = -(Ax * X0 + Ay * Y0 + Ad) / Az;

            Point3d P0 = new Point3d(X0, Y0, Z0, lc);

            if (P0.BelongsTo(this))
            {
                // the plane is tangent to ellipsoid
                return(P0);
            }
            else if (P0.IsInside(this))
            {
                Vector3d q  = P0.ToVector.ConvertTo(lc);
                Matrix3d D1 = Matrix3d.DiagonalMatrix(1 / a, 1 / b, 1 / c);
                Vector3d r  = plane.Normal.ConvertTo(lc).OrthogonalVector.Normalized;
                Vector3d s  = plane.Normal.ConvertTo(lc).Cross(r).Normalized;

                double omega = 0;
                double qq, qr, qs, rr, ss, rs;
                if (!GeometRi3D.AlmostEqual((D1 * r) * (D1 * s), 0))
                {
                    rr = (D1 * r) * (D1 * r);
                    rs = (D1 * r) * (D1 * s);
                    ss = (D1 * s) * (D1 * s);
                    if (GeometRi3D.AlmostEqual(rr - ss, 0))
                    {
                        omega = PI / 4;
                    }
                    else
                    {
                        omega = 0.5 * Atan(2.0 * rs / (rr - ss));
                    }
                    Vector3d rprim = Cos(omega) * r + Sin(omega) * s;
                    Vector3d sprim = -Sin(omega) * r + Cos(omega) * s;
                    r = rprim;
                    s = sprim;
                }

                qq = (D1 * q) * (D1 * q);
                qr = (D1 * q) * (D1 * r);
                qs = (D1 * q) * (D1 * s);
                rr = (D1 * r) * (D1 * r);
                ss = (D1 * s) * (D1 * s);

                double d = qq - qr * qr / rr - qs * qs / ss;
                AA = Sqrt((1 - d) / rr);
                BB = Sqrt((1 - d) / ss);

                return(new Ellipse(P0, AA * r, BB * s));
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Returns shortest distance from point to the plane
 /// </summary>
 public double DistanceTo(Plane3d s)
 {
     s.SetCoord(this.Coord);
     return(Abs(X * s.A + Y * s.B + Z * s.C + s.D) / Sqrt(Math.Pow(s.A, 2) + Math.Pow(s.B, 2) + Math.Pow(s.C, 2)));
 }