Пример #1
0
        /// <summary>
        /// Get intersection of plane with triangle.
        /// Returns 'null' (no intersection) or object of type 'Triangle', 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Plane3d s)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * Max(AB, Max(BC, AC));
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(s);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

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

            if (s.IsParallelTo(st))
            {
                if (A.BelongsTo(s))
                {
                    return(this.Copy());
                }
                else
                {
                    return(null);
                }
            }

            Line3d l = (Line3d)s.IntersectionWith(st);

            return(this.IntersectionWith(l));
        }
Пример #2
0
        /// <summary>
        /// Intersection of ellipse with plane.
        /// Returns 'null' (no intersection) or object of type 'Ellipse', 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Plane3d s)
        {
            // Relative tolerance ================================
            if (!GeometRi3D.UseAbsoluteTolerance)
            {
                double tol = GeometRi3D.Tolerance;
                GeometRi3D.Tolerance            = tol * this.A;
                GeometRi3D.UseAbsoluteTolerance = true;
                object result = this.IntersectionWith(s);
                GeometRi3D.UseAbsoluteTolerance = false;
                GeometRi3D.Tolerance            = tol;
                return(result);
            }
            //====================================================

            if (this.Normal.IsParallelTo(s.Normal))
            {
                if (this.Center.BelongsTo(s))
                {
                    // coplanar objects
                    return(this.Copy());
                }
                else
                {
                    // parallel objects
                    return(null);
                }
            }
            else
            {
                Line3d l = (Line3d)s.IntersectionWith(new Plane3d(this.Center, this.Normal));
                return(this.IntersectionWith(l));
            }
        }
Пример #3
0
        /// <summary>
        /// Intersection of circle with plane.
        /// Returns 'null' (no intersection) or object of type 'Circle3d', 'Point3d' or 'Segment3d'.
        /// </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;
            }
            //====================================================

            if (this.Normal.IsParallelTo(s.Normal))
            {
                if (this.Center.BelongsTo(s))
                {
                    // coplanar objects
                    return this.Copy();
                }
                else
                {
                    // parallel objects
                    return null;
                }
            }
            else
            {
                Line3d l = (Line3d)s.IntersectionWith(new Plane3d(this.Center, this.Normal));
                Coord3d local_coord = new Coord3d(this.Center, l.Direction, this.Normal.Cross(l.Direction));
                Point3d p = l.Point.ConvertTo(local_coord);

                if (GeometRi3D.Greater(Abs(p.Y), this.R))
                {
                    return null;
                }
                else if (GeometRi3D.AlmostEqual(p.Y, this.R))
                {
                    return new Point3d(0, this.R, 0, local_coord);
                }
                else if (GeometRi3D.AlmostEqual(p.Y, -this.R))
                {
                    return new Point3d(0, -this.R, 0, local_coord);
                }
                else
                {
                    double d = Sqrt(Math.Pow(this.R, 2) - Math.Pow(p.Y, 2));
                    Point3d p1 = new Point3d(-d, p.Y, 0, local_coord);
                    Point3d p2 = new Point3d(d, p.Y, 0, local_coord);
                    return new Segment3d(p1, p2);
                }
            }

        }
Пример #4
0
        /// <summary>
        /// Intersection of circle with plane.
        /// Returns 'null' (no intersection) or object of type 'Circle3d', 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Plane3d s)
        {
            if (this.Normal.IsParallelTo(s.Normal))
            {
                if (this.Center.BelongsTo(s))
                {
                    // coplanar objects
                    return(this.Copy());
                }
                else
                {
                    // parallel objects
                    return(null);
                }
            }
            else
            {
                Line3d  l           = (Line3d)s.IntersectionWith(new Plane3d(this.Center, this.Normal));
                Coord3d local_coord = new Coord3d(this.Center, l.Direction, this.Normal.Cross(l.Direction));
                Point3d p           = l.Point.ConvertTo(local_coord);

                if (GeometRi3D.Greater(Abs(p.Y), this.R))
                {
                    return(null);
                }
                else if (GeometRi3D.AlmostEqual(p.Y, this.R))
                {
                    return(new Point3d(0, this.R, 0, local_coord));
                }
                else if (GeometRi3D.AlmostEqual(p.Y, -this.R))
                {
                    return(new Point3d(0, -this.R, 0, local_coord));
                }
                else
                {
                    double  d  = Sqrt(Math.Pow(this.R, 2) - Math.Pow(p.Y, 2));
                    Point3d p1 = new Point3d(-d, p.Y, 0, local_coord);
                    Point3d p2 = new Point3d(d, p.Y, 0, local_coord);
                    return(new Segment3d(p1, p2));
                }
            }
        }
Пример #5
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));
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Intersection of ellipse with plane.
        /// Returns 'null' (no intersection) or object of type 'Ellipse', 'Point3d' or 'Segment3d'.
        /// </summary>
        public object IntersectionWith(Plane3d s)
        {
            if (this.Normal.IsParallelTo(s.Normal))
            {
                if (this.Center.BelongsTo(s))
                {
                    // coplanar objects
                    return(this.Copy());
                }
                else
                {
                    // parallel objects
                    return(null);
                }
            }
            else
            {
                Line3d   l           = (Line3d)s.IntersectionWith(new Plane3d(this.Center, this.Normal));
                Coord3d  local_coord = new Coord3d(this.Center, this._v1, this._v2);
                Point3d  p           = l.Point.ConvertTo(local_coord);
                Vector3d v           = l.Direction.ConvertTo(local_coord);
                double   a           = this.A;
                double   b           = this.B;

                if (Abs(v.Y / v.X) > 100)
                {
                    // line is almost vertical, rotate local coord
                    local_coord = new Coord3d(this.Center, this._v2, this._v1);
                    p           = l.Point.ConvertTo(local_coord);
                    v           = l.Direction.ConvertTo(local_coord);
                    a           = this.B;
                    b           = this.A;
                }

                // Find intersection of line and ellipse (2D)
                // Solution from: http://www.ambrsoft.com/TrigoCalc/Circles2/Ellipse/EllipseLine.htm

                // Line equation in form: y = mx + c
                double m = v.Y / v.X;
                double c = p.Y - m * p.X;

                double amb = Math.Pow(a, 2) * Math.Pow(m, 2) + Math.Pow(b, 2);
                double det = amb - Math.Pow(c, 2);
                if (det < -GeometRi3D.Tolerance)
                {
                    return(null);
                }
                else if (GeometRi3D.AlmostEqual(det, 0))
                {
                    double x = -Math.Pow(a, 2) * m * c / amb;
                    double y = Math.Pow(b, 2) * c / amb;
                    return(new Point3d(x, y, 0, local_coord));
                }
                else
                {
                    double x1 = (-Math.Pow(a, 2) * m * c + a * b * Sqrt(det)) / amb;
                    double x2 = (-Math.Pow(a, 2) * m * c - a * b * Sqrt(det)) / amb;
                    double y1 = (Math.Pow(b, 2) * c + a * b * m * Sqrt(det)) / amb;
                    double y2 = (Math.Pow(b, 2) * c - a * b * m * Sqrt(det)) / amb;
                    return(new Segment3d(new Point3d(x1, y1, 0, local_coord), new Point3d(x2, y2, 0, local_coord)));
                }
            }
        }
Пример #7
0
 /// <summary>
 /// Get intersection of line with plane.
 /// Returns 'null' (no intersection) or object of type 'Point3d' or 'Line3d'.
 /// </summary>
 public virtual object IntersectionWith(Plane3d s)
 {
     return(s.IntersectionWith(this));
 }