/// <summary> /// Reflect line in given plane /// </summary> public virtual Line3d ReflectIn(Plane3d s) { return(new Line3d(this.Point.ReflectIn(s), this.Direction.ReflectIn(s))); }
/// <summary> /// Reflect triangle in given plane /// </summary> public Triangle ReflectIn(Plane3d s) { return(new Triangle(_a.ReflectIn(s), _b.ReflectIn(s), _c.ReflectIn(s))); }
/// <summary> /// Reflect ray in given plane /// </summary> public Ray3d ReflectIn(Plane3d s) { return(new Ray3d(this.Point.ReflectIn(s), this.Direction.ReflectIn(s))); }
/// <summary> /// Orthogonal projection of the circle to plane /// </summary> public Ellipse ProjectionTo(Plane3d s) { return(this.ToEllipse.ProjectionTo(s)); }
/// <summary> /// Reflect circle in given plane /// </summary> public Circle3d ReflectIn(Plane3d s) { return(new Circle3d(this.Center.ReflectIn(s), this.R, this.Normal.ReflectIn(s))); }
/// <summary> /// Reflect sphere in given plane /// </summary> public Sphere ReflectIn(Plane3d s) { return(new Sphere(this.Center.ReflectIn(s), this.R)); }
/// <summary> /// Reflect segment in given plane /// </summary> public virtual Segment3d ReflectIn(Plane3d s) { return(new Segment3d(P1.ReflectIn(s), P2.ReflectIn(s))); }
/// <summary> /// Reflect plane in given plane /// </summary> public Plane3d ReflectIn(Plane3d s) { return(new Plane3d(this.Point.ReflectIn(s), this.Normal.ReflectIn(s))); }
/// <summary> /// Orthogonal projection of the sphere to the plane /// </summary> public Circle3d ProjectionTo(Plane3d s) { Point3d p = this.Center.ProjectionTo(s); return(new Circle3d(p, this.R, s.Normal)); }
/// <summary> /// Reflect ellipse in given plane /// </summary> public Ellipse ReflectIn(Plane3d s) { return(new Ellipse(this.Center.ReflectIn(s), _v1.ReflectIn(s), _v2.ReflectIn(s))); }
/// <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))); } } }
/// <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.IsOnBoundary(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); } }
/// <summary> /// Reflect point in given plane /// </summary> public Point3d ReflectIn(Plane3d s) { Vector3d v = new Vector3d(this, this.ProjectionTo(s)); return(this.Translate(2 * v)); }
/// <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)); }