/// <summary> /// Initializes circle passing through three points. /// </summary> public Circle3d(Point3d p1, Point3d p2, Point3d p3) { Vector3d v1 = new Vector3d(p1, p2); Vector3d v2 = new Vector3d(p1, p3); if (v1.Cross(v2).Norm < GeometRi3D.Tolerance) { throw new Exception("Collinear points"); } Coord3d CS = new Coord3d(p1, v1, v2); Point3d a1 = p1.ConvertTo(CS); Point3d a2 = p2.ConvertTo(CS); Point3d a3 = p3.ConvertTo(CS); double d1 = Math.Pow(a1.X, 2) + Math.Pow(a1.Y, 2); double d2 = Math.Pow(a2.X, 2) + Math.Pow(a2.Y, 2); double d3 = Math.Pow(a3.X, 2) + Math.Pow(a3.Y, 2); double f = 2.0 * (a1.X * (a2.Y - a3.Y) - a1.Y * (a2.X - a3.X) + a2.X * a3.Y - a3.X * a2.Y); double X = (d1 * (a2.Y - a3.Y) + d2 * (a3.Y - a1.Y) + d3 * (a1.Y - a2.Y)) / f; double Y = (d1 * (a3.X - a2.X) + d2 * (a1.X - a3.X) + d3 * (a2.X - a1.X)) / f; //_point = (new Point3d(X, Y, 0, CS)).ConvertTo(p1.Coord); _point = new Point3d(X, Y, 0, CS); _point = _point.ConvertTo(p1.Coord); _r = Sqrt((X - a1.X) * (X - a1.X) + (Y - a1.Y) * (Y - a1.Y)); _normal = v1.Cross(v2); }
/// <summary> /// Return Axis Aligned Bounding Box (AABB) in given coordinate system. /// </summary> public Box3d BoundingBox(Coord3d coord = null) { coord = (coord == null) ? Coord3d.GlobalCS : coord; Point3d c = _center.ConvertTo(coord); double mx = c.X; double my = c.Y; double mz = c.Z; foreach (Point3d p in this.ListOfPoints) { Point3d t = p.ConvertTo(coord); if (t.X < mx) { mx = t.X; } if (t.Y < my) { my = t.Y; } if (t.Z < mz) { mz = t.Z; } } return(new Box3d(c, 2.0 * (c.X - mx), 2.0 * (c.Y - my), 2.0 * (c.Z - mz), coord)); }
/// <summary> /// Initializes unit box in the origin of the reference coordinate system aligned with coordinate axes. /// </summary> /// <param name="coord">Reference coordinate system.</param> public Box3d(Coord3d coord = null) { coord = (coord == null) ? Coord3d.GlobalCS : coord; _center = new Point3d(coord); _lx = _ly = _lz = 1.0; _r = new Rotation(coord); }
/// <summary> /// Default constructor, initializes zero point. /// </summary> /// <param name="coord">Reference coordinate system (default - Coord3d.GlobalCS).</param> public Point3d(Coord3d coord = null) { _x = 0.0; _y = 0.0; _z = 0.0; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <summary> /// Initiaizes point object using coordinates. /// </summary> /// <param name="coord">Reference coordinate system (default - Coord3d.GlobalCS).</param> public Point3d(double x, double y, double z, Coord3d coord = null) { _x = x; _y = y; _z = z; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
internal override int _PointLocation(Point3d p) { Coord3d coord = new Coord3d(this.Center, this.V1, this.V2); p = p.ConvertTo(coord); if (GeometRi3D.UseAbsoluteTolerance) { if ((Abs(p.X) - L1 / 2) <= GeometRi3D.Tolerance && (Abs(p.Y) - L2 / 2) <= GeometRi3D.Tolerance && (Abs(p.Z) - L3 / 2) <= GeometRi3D.Tolerance) { if ((Abs(p.X) - L1 / 2) < -GeometRi3D.Tolerance && (Abs(p.Y) - L2 / 2) < -GeometRi3D.Tolerance && (Abs(p.Z) - L3 / 2) < -GeometRi3D.Tolerance) { return(1); // Point is strictly inside box } else { return(0); // Point is on boundary } } else { return(-1); // Point is outside } } else { double tol = GeometRi3D.Tolerance; GeometRi3D.Tolerance = tol * this.Diagonal; GeometRi3D.UseAbsoluteTolerance = true; int result = this._PointLocation(p); GeometRi3D.UseAbsoluteTolerance = false; GeometRi3D.Tolerance = tol; return(result); } }
internal override int _PointLocation(Point3d p) { Coord3d lc = new Coord3d(this.Center, this.SemiaxisA, this.SemiaxisB); p = p.ConvertTo(lc); if (GeometRi3D.UseAbsoluteTolerance) { double dist = this.ClosestPoint(p).DistanceTo(p); if (GeometRi3D.AlmostEqual(dist, 0)) { return(0); // Point is on boundary } if (GeometRi3D.Smaller(p.X * p.X / (A * A) + p.Y * p.Y / (B * B) + p.Z * p.Z / (C * C), 1.0)) { return(1); // Point is strictly inside box } return(-1); // Point is outside } else { double tol = GeometRi3D.Tolerance; GeometRi3D.Tolerance = tol * this.A; GeometRi3D.UseAbsoluteTolerance = true; int result = this._PointLocation(p); GeometRi3D.UseAbsoluteTolerance = false; GeometRi3D.Tolerance = tol; return(result); } }
/// <summary> /// Initializes vector object using components in reference coordinate system. /// </summary> /// <param name="coord">Reference coordinate system (default - Coord3d.GlobalCS).</param> public Vector3d(double X, double Y, double Z, Coord3d coord = null) { this.val = new double[3]; this.val[0] = X; this.val[1] = Y; this.val[2] = Z; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <summary> /// Default constructor, initializes zero vector. /// </summary> /// <param name="coord">Reference coordinate system (default - Coord3d.GlobalCS).</param> public Vector3d(Coord3d coord = null) { this.val = new double[3]; this.val[0] = 0.0; this.val[1] = 0.0; this.val[2] = 0.0; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <summary> /// Initializes axis aligned box in local coordinate system. /// </summary> /// <param name="center">Center point of the box.</param> /// <param name="lx">First dimension.</param> /// <param name="ly">Second dimension.</param> /// <param name="lz">Third dimension.</param> /// <param name="coord">Local coordinate system.</param> public Box3d(Point3d center, double lx, double ly, double lz, Coord3d coord) { _center = center.Copy(); _lx = lx; _ly = ly; _lz = lz; _r = new Rotation(coord); }
/// <summary> /// Initializes axis aligned box in local coordinate system. /// </summary> /// <param name="center">Center point of the box.</param> /// <param name="lx">First dimension.</param> /// <param name="ly">Second dimension.</param> /// <param name="lz">Third dimension.</param> /// <param name="coord">Local coordinate system.</param> public Box3d(Point3d center, double lx, double ly, double lz, Coord3d coord) { _center = center.Copy(); _lx = lx; _ly = ly; _lz = lz; _r = new Rotation(coord); _local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose()); }
/// <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); } } }
/// <summary> /// Initializes vector object as radius vector of a point in reference coordinate system. /// </summary> public Vector3d(Point3d p, Coord3d coord = null) { p = p.ConvertTo(coord); this.val = new double[3]; this.val[0] = p.X; this.val[1] = p.Y; this.val[2] = p.Z; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <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); } Coord3d cs = (Coord3d)obj; return(this._name == cs._name); }
/// <summary> /// Reflect box in given plane /// <para>The order of corner points will be changed during reflection operation.</para> /// </summary> public virtual Box3d ReflectIn(Plane3d s) { Point3d new_center = this.Center.ReflectIn(s); Vector3d nV1 = this.V1.ReflectIn(s); Vector3d nV2 = this.V2.ReflectIn(s); Coord3d coord = new Coord3d(new_center, nV1, nV2); Rotation new_rotation = new Rotation(coord); return(new Box3d(new_center, _lx, _ly, _lz, new_rotation)); }
/// <summary> /// String representation of an object in reference coordinate system. /// </summary> public String ToString(Coord3d coord) { if (coord == null) { coord = Coord3d.GlobalCS; } Vector3d v = this.ConvertTo(coord); return(string.Format("Vector3d -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", v.X, v.Y, v.Z)); }
/// <summary> /// String representation of an object in reference coordinate system. /// </summary> public string ToString(Coord3d coord) { if (coord == null) { coord = Coord3d.GlobalCS; } Quaternion q = this.ConvertTo(coord); return(string.Format("Quaternion -> ({0,10:g5}, {1,10:g5}, {2,10:g5}, {3,10:g5})", q.W, q.X, q.Y, q.Z)); }
/// <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); }
/// <summary> /// Point on box (including interior points) closest to target point "p". /// </summary> public Point3d ClosestPoint(Point3d p) { Coord3d local_coord = this.LocalCoord(); p = p.ConvertTo(local_coord); double x = GeometRi3D.Clamp(p.X, -_lx / 2, _lx / 2); double y = GeometRi3D.Clamp(p.Y, -_ly / 2, _ly / 2); double z = GeometRi3D.Clamp(p.Z, -_lz / 2, _lz / 2); return(new Point3d(x, y, z, local_coord)); }
/// <summary> /// Initiaizes point object using double array. /// </summary> /// <param name="coord">Reference coordinate system (default - Coord3d.GlobalCS).</param> public Point3d(double[] a, Coord3d coord = null) { if (a.GetUpperBound(0) < 2) { throw new Exception("Point3d: Array size mismatch"); } _x = a[0]; _y = a[1]; _z = a[2]; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <summary> /// String representation of an object in reference coordinate system. /// </summary> public string ToString(Coord3d coord) { string nl = System.Environment.NewLine; Rotation r = this.ConvertTo(coord); string str = "Rotation (reference coord.sys. " + coord.Name + "):" + nl; str += string.Format("Row1 -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", r[0, 0], r[0, 1], r[0, 2]) + nl; str += string.Format("Row2 -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", r[1, 0], r[1, 1], r[1, 2]) + nl; str += string.Format("Row3 -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", r[2, 0], r[2, 1], r[2, 2]); return(str); }
/// <summary> /// Initializes quaternion using axis of rotation and angle. /// </summary> public Quaternion(Vector3d axis, double angle) { Vector3d v = axis.Normalized; _w = Cos(angle / 2); _x = v.X * Sin(angle / 2); _y = v.Y * Sin(angle / 2); _z = v.Z * Sin(angle / 2); _coord = axis.Coord; }
/// <summary> /// Initializes rotation, equal to the rotation from global CS to 'coord'. /// </summary> public Rotation(Coord3d coord) { if (coord == null) { _r = Matrix3d.Identity(); } else { _r = coord.Axes.Transpose(); } _coord = Coord3d.GlobalCS; }
/// <summary> /// Initializes unit box in the origin of the reference coordinate system aligned with coordinate axes. /// </summary> /// <param name="coord">Reference coordinate system.</param> public Box3d(Coord3d coord = null) { _center = new Point3d(coord); _lx = _ly = _lz = 1.0; _r = new Rotation(coord); if (coord != null) { // do not set local_coord for box aligned with global CS _local_coord = new Coord3d(_center, _r.ConvertToGlobal().ToRotationMatrix.Transpose()); } coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <summary> /// String representation of an object in reference coordinate system. /// </summary> public String ToString(Coord3d coord) { if (coord == null) { coord = Coord3d.GlobalCS; } Point3d p = this.ConvertTo(coord); string str = string.Format("Point3d -> ({0,10:g5}, {1,10:g5}, {2,10:g5})", p.X, p.Y, p.Z) + System.Environment.NewLine; return(str); }
/// <summary> /// Initializes quaternion using double array. /// </summary> /// <param name="coord">Reference coordinate system (default - Coord3d.GlobalCS).</param> public Quaternion(double[] q, Coord3d coord = null) { if (q.GetUpperBound(0) < 3) { throw new Exception("Quaternion: Array size mismatch"); } _w = q[0]; _x = q[1]; _y = q[2]; _z = q[3]; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <summary> /// Convert quaternion to reference coordinate system. /// </summary> public Quaternion ConvertTo(Coord3d coord) { if (_coord == null || object.ReferenceEquals(_coord, Coord3d.GlobalCS)) { return(this.Copy()); } Vector3d axis = this.ToAxis; double angle = this.ToAngle; axis = axis.ConvertTo(coord); return(new Quaternion(axis, angle)); }
/// <summary> /// Initializes vector using double array. /// </summary> /// <param name="coord">Reference coordinate system (default - Coord3d.GlobalCS).</param> public Vector3d(double[] a, Coord3d coord = null) { if (a.GetUpperBound(0) < 2) { throw new Exception("Vector3d: Array size mismatch"); } this.val = new double[3]; this.val[0] = a[0]; this.val[1] = a[1]; this.val[2] = a[2]; _coord = (coord == null) ? Coord3d.GlobalCS : coord; }
/// <summary> /// Initializes vector object using two points in reference coordinate system of the first point. /// </summary> /// <param name="p1">Start point.</param> /// <param name="p2">End point.</param> public Vector3d(Point3d p1, Point3d p2) { if (p1.Coord != p2.Coord) { p2 = p2.ConvertTo(p1.Coord); } this.val = new double[3]; this.val[0] = p2.X - p1.X; this.val[1] = p2.Y - p1.Y; this.val[2] = p2.Z - p1.Z; _coord = p1.Coord; }
/// <summary> /// Convert vector to reference coordinate system. /// </summary> public Vector3d ConvertTo(Coord3d coord) { Vector3d v1 = this.Copy(); v1 = v1.ConvertToGlobal(); if (coord != null && !object.ReferenceEquals(coord, Coord3d.GlobalCS)) { v1 = coord.Axes * v1; v1._coord = coord; } return(v1); }