Esempio n. 1
0
        /// <summary>
        /// Create a circle from three points which lie along its circumference.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        public Circle3D(Point3D p1, Point3D p2, Point3D p3)
        {
https:      //www.physicsforums.com/threads/equation-of-a-circle-through-3-points-in-3d-space.173847/
            Vector3D p1p2 = p2 - p1;
            Vector3D p2p3 = p3 - p2;

            this.Axis = p1p2.CrossProduct(p2p3).Normalize();

            Point3D midPointA = p1 + 0.5 * p1p2;
            Point3D midPointB = p2 + 0.5 * p2p3;

            Vector3D directionA = p1p2.CrossProduct(this.Axis);
            Vector3D directionB = p2p3.CrossProduct(this.Axis);

            Ray3D bisectorA = new Ray3D(midPointA, directionA);
            Plane bisectorB = new Plane(midPointB, midPointB + directionB.Normalize(), midPointB + this.Axis);

            var center = bisectorA.IntersectionWith(bisectorB);

            if (center == null)
            {
                throw new ArgumentException("A circle cannot be created from these points, are they colinear?");
            }

            this.CenterPoint = (Point3D)center;
            this.Radius      = this.CenterPoint.DistanceTo(p1);
        }
Esempio n. 2
0
        /// <summary>
        /// Finds the intersection of the two planes, throws if they are parallel
        /// http://mathworld.wolfram.com/Plane-PlaneIntersection.html
        /// </summary>
        /// <param name="intersectingPlane"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public Ray3D IntersectionWith(Plane intersectingPlane, double tolerance = float.Epsilon)
        {
            var a = new DenseMatrix(2, 3);

            a.SetRow(0, this.Normal.ToVector());
            a.SetRow(1, intersectingPlane.Normal.ToVector());
            var svd = a.Svd(true);

            if (svd.S[1] < tolerance)
            {
                throw new ArgumentException("Planes are parallel");
            }

            var y = new DenseMatrix(2, 1);

            y[0, 0] = -1 * this.D;
            y[1, 0] = -1 * intersectingPlane.D;

            Matrix <double> pointOnIntersectionLine = svd.Solve(y);
            var             throughPoint            = new Point3D(pointOnIntersectionLine.Column(0));

            var direction = new UnitVector3D(svd.VT.Row(2));

            return(new Ray3D(throughPoint, direction));
        }
Esempio n. 3
0
        /// <summary>
        /// Transforms a vector and returns the transformed vector
        /// </summary>
        /// <param name="v">a unit vector</param>
        /// <returns>A transformed vector</returns>
        public Vector3D Transform(UnitVector3D v)
        {
            var v3 = Vector <double> .Build.Dense(new[] { v.X, v.Y, v.Z });

            this.GetRotationSubMatrix().Multiply(v3, v3);
            return(new Vector3D(v3[0], v3[1], v3[2]));
        }
Esempio n. 4
0
        public bool IsParallelTo(UnitVector3D othervector, double tolerance = 1e-6)
        {
            var @this = this.Normalize();
            var dp    = Math.Abs(@this.DotProduct(othervector));

            return(Math.Abs(1 - dp) < tolerance);
        }
Esempio n. 5
0
        public Plane Rotate(UnitVector3D aboutVector, Angle angle)
        {
            var rootPoint          = this.RootPoint;
            var rotatedPoint       = rootPoint.Rotate(aboutVector, angle);
            var rotatedPlaneVector = this.Normal.Rotate(aboutVector, angle);

            return(new Plane(rotatedPlaneVector, rotatedPoint));
        }
Esempio n. 6
0
        public void ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            var e = (XElement)XNode.ReadFrom(reader);

            XmlExt.SetReadonlyField(ref this, l => l.ThroughPoint, Point3D.ReadFrom(e.SingleElement("ThroughPoint").CreateReader()));
            XmlExt.SetReadonlyField(ref this, l => l.Direction, UnitVector3D.ReadFrom(e.SingleElement("Direction").CreateReader()));
        }
Esempio n. 7
0
        /// <summary>
        /// Creates a coordinate system that rotates
        /// </summary>
        /// <param name="angle">Angle to rotate</param>
        /// <param name="v">Vector to rotate about</param>
        /// <returns>A rotating coordinate system</returns>
        public static CoordinateSystem Rotation(Angle angle, UnitVector3D v)
        {
            var m = Build.Dense(4, 4);

            m.SetSubMatrix(0, 3, 0, 3, Matrix3D.RotationAroundArbitraryVector(v, angle));
            m[3, 3] = 1;
            return(new CoordinateSystem(m));
        }
Esempio n. 8
0
        /// <summary>
        /// Sets to the matrix of rotation that aligns the 'from' vector with the 'to' vector.
        /// The optional Axis argument may be used when the two vectors are perpendicular and in opposite directions to specify a specific solution, but is otherwise ignored.
        /// </summary>
        /// <param name="fromVector3D">Input Vector object to align from.</param>
        /// <param name="toVector3D">Input Vector object to align to.</param>
        /// <param name="axis">Input Vector object. </param>
        /// <returns>A rotated coordinate system </returns>
        public static CoordinateSystem RotateTo(UnitVector3D fromVector3D, UnitVector3D toVector3D, UnitVector3D?axis = null)
        {
            var r = Matrix3D.RotationTo(fromVector3D, toVector3D, axis);
            var coordinateSystem = new CoordinateSystem();
            var cs = SetRotationSubMatrix(r, coordinateSystem);

            return(cs);
        }
Esempio n. 9
0
 public Vector3D CrossProduct(UnitVector3D inVector3D)
 {
     var x = (this.Y*inVector3D.Z) - (this.Z*inVector3D.Y);
     var y = (this.Z*inVector3D.X) - (this.X*inVector3D.Z);
     var z = (this.X*inVector3D.Y) - (this.Y*inVector3D.X);
     var v = new Vector3D(x, y, z);
     return v;
 }
Esempio n. 10
0
        public Vector3D CrossProduct(UnitVector3D other)
        {
            var x = (this.Y * other.Z) - (this.Z * other.Y);
            var y = (this.Z * other.X) - (this.X * other.Z);
            var z = (this.X * other.Y) - (this.Y * other.X);
            var v = new Vector3D(x, y, z);

            return(v);
        }
Esempio n. 11
0
        public void ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            var e = (XElement)XNode.ReadFrom(reader);

            XmlExt.SetReadonlyField(ref this, l => l.RootPoint, Point3D.ReadFrom(e.SingleElement("RootPoint").CreateReader()));
            XmlExt.SetReadonlyField(ref this, l => l.Normal, UnitVector3D.ReadFrom(e.SingleElement("Normal").CreateReader()));
            XmlExt.SetReadonlyField(ref this, l => l.D, -this.RootPoint.ToVector3D().DotProduct(this.Normal));
        }
Esempio n. 12
0
        /// <inheritdoc/>
        void IXmlSerializable.ReadXml(XmlReader reader)
        {
            reader.MoveToContent();
            var e = (XElement)XNode.ReadFrom(reader);

            this = new Ray3D(
                Point3D.ReadFrom(e.SingleElement("ThroughPoint").CreateReader()),
                UnitVector3D.ReadFrom(e.SingleElement("Direction").CreateReader()));
        }
Esempio n. 13
0
        public bool Equals(UnitVector3D other, double tolerance)
        {
            if (tolerance < 0)
            {
                throw new ArgumentException("epsilon < 0");
            }

            return Math.Abs(other.X - this.X) < tolerance &&
                   Math.Abs(other.Y - this.Y) < tolerance &&
                   Math.Abs(other.Z - this.Z) < tolerance;
        }
Esempio n. 14
0
        /// <summary>
        /// Throws if StartPoint == EndPoint
        /// </summary>
        /// <param name="startPoint"></param>
        /// <param name="endPoint"></param>
        public Line3D(Point3D startPoint, Point3D endPoint)
        {
            this.StartPoint = startPoint;
            this.EndPoint   = endPoint;
            if (this.StartPoint == this.EndPoint)
            {
                throw new ArgumentException("StartPoint == EndPoint");
            }

            this._length    = -1.0;
            this._direction = new UnitVector3D();
        }
Esempio n. 15
0
        public static Matrix <double> RotationAroundArbitraryVector(UnitVector3D aboutVector, Angle angle)
        {
            // http://en.wikipedia.org/wiki/Rotation_matrix
            var unitTensorProduct  = aboutVector.GetUnitTensorProduct();
            var crossproductMatrix = aboutVector.CrossProductMatrix; // aboutVector.Clone().CrossProduct(aboutVector.Clone());

            var r1     = DenseMatrix.CreateIdentity(3).Multiply(Math.Cos(angle.Radians));
            var r2     = crossproductMatrix.Multiply(Math.Sin(angle.Radians));
            var r3     = unitTensorProduct.Multiply(1 - Math.Cos(angle.Radians));
            var totalR = r1.Add(r2).Add(r3);

            return(totalR);
        }
Esempio n. 16
0
        /// <summary>
        /// http://www.had2know.com/academics/equation-plane-through-3-points.html
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        public Plane(Point3D p1, Point3D p2, Point3D p3)
        {
            if (p1 == p2 || p1 == p3 || p2 == p3)
            {
                throw new ArgumentException("Must use three different points");
            }
            Vector3D v1    = new Vector3D(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z);
            Vector3D v2    = new Vector3D(p3.X - p1.X, p3.Y - p1.Y, p3.Z - p1.Z);
            Vector3D cross = v1.CrossProduct(v2);

            if (cross.Length <= float.Epsilon)
            {
                throw new ArgumentException("The 3 points should not be on the same line");
            }
            this.RootPoint = p1;
            this.Normal    = cross.Normalize();
            this.D         = -this.RootPoint.ToVector3D().DotProduct(this.Normal);
        }
Esempio n. 17
0
        /// <summary>
        /// Sets to the matrix of rotation that would align the 'from' vector with the 'to' vector.
        /// The optional Axis argument may be used when the two vectors are perpendicular and in opposite directions to specify a specific solution, but is otherwise ignored.
        /// </summary>
        /// <param name="fromVector">Input Vector object to align from.</param>
        /// <param name="toVector">Input Vector object to align to.</param>
        /// <param name="axis">Input Vector object. </param>
        public static Matrix <double> RotationTo(UnitVector3D fromVector, UnitVector3D toVector, UnitVector3D?axis = null)
        {
            if (fromVector == toVector)
            {
                return(DenseMatrix.CreateIdentity(3));
            }

            if (fromVector.IsParallelTo(toVector))
            {
                if (axis == null)
                {
                    axis = fromVector.Orthogonal;
                }
            }
            else
            {
                axis = fromVector.CrossProduct(toVector);
            }

            var signedAngleTo = fromVector.SignedAngleTo(toVector, axis.Value);

            return(RotationAroundArbitraryVector(axis.Value, signedAngleTo));
        }
Esempio n. 18
0
        public Point3D Rotate(UnitVector3D aboutVector, Angle angle)
        {
            var cs = CoordinateSystem.Rotation(angle, aboutVector);

            return(cs.Transform(this));
        }
Esempio n. 19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Plane"/> struct.
 /// Constructs a Plane from the given normal and distance along the normal from the origin.
 /// </summary>
 /// <param name="normal">The Plane's normal vector.</param>
 /// <param name="rootPoint">A point in the plane.</param>
 public Plane(Point3D rootPoint, UnitVector3D normal)
     : this(normal, normal.DotProduct(rootPoint))
 {
 }
Esempio n. 20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Plane"/> struct.
 /// Constructs a Plane from the given normal and distance along the normal from the origin.
 /// </summary>
 /// <param name="normal">The Plane's normal vector.</param>
 /// <param name="offset">The Plane's distance from the origin along its normal vector.</param>
 public Plane(UnitVector3D normal, double offset = 0)
 {
     this.Normal = normal;
     this.D      = -offset;
 }
Esempio n. 21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Plane"/> struct.
 /// Constructs a Plane from the X, Y, and Z components of its normal, and its distance from the origin on that normal.
 /// </summary>
 /// <param name="x">The X-component of the normal.</param>
 /// <param name="y">The Y-component of the normal.</param>
 /// <param name="z">The Z-component of the normal.</param>
 /// <param name="d">The distance of the Plane along its normal from the origin.</param>
 public Plane(double x, double y, double z, double d)
     : this(UnitVector3D.Create(x, y, z), -d)
 {
 }
Esempio n. 22
0
 public Ray3D Project(UnitVector3D vector3DToProject)
 {
     return(this.Project(vector3DToProject.ToVector3D()));
 }
Esempio n. 23
0
 /// <summary>
 /// Returns a vector that is this vector rotated the signed angle around the about vector
 /// </summary>
 /// <param name="about"></param>
 /// <param name="angle"></param>
 /// <returns></returns>
 public Vector3D Rotate(UnitVector3D about, Angle angle)
 {
     var cs = CoordinateSystem.Rotation(angle, about);
     return cs.Transform(this);
 }
Esempio n. 24
0
 /// <summary>
 /// Returns a vector that is this vector rotated the signed angle around the about vector
 /// </summary>
 /// <typeparam name="T">Constraining it like this does not box</typeparam>
 /// <param name="about"></param>
 /// <param name="angle"></param>
 /// <param name="angleUnit"></param>
 /// <returns></returns>
 public Vector3D Rotate<T>(UnitVector3D about, double angle, T angleUnit)
     where T : IAngleUnit
 {
     return Rotate(about, Angle.From(angle, angleUnit));
 }
Esempio n. 25
0
 /// <summary>
 /// Compute the angle between this vector and a unit vector using the arccosine of the dot product.
 /// </summary>
 /// <param name="v">The other vector</param>
 /// <returns>The angle between the vectors, with a range between 0° and 180°</returns>
 public Angle AngleTo(UnitVector3D v)
 {
     var uv = this.Normalize();
     return uv.AngleTo(v);
 }
Esempio n. 26
0
 /// <summary>
 /// Returns signed angle
 /// </summary>
 /// <param name="v">The vector to calculate the signed angle to </param>
 /// <param name="about">The vector around which to rotate to get the correct sign</param>
 public Angle SignedAngleTo(UnitVector3D v, UnitVector3D about)
 {
     return this.Normalize().SignedAngleTo(v, about);
 }
Esempio n. 27
0
 public double DotProduct(UnitVector3D v)
 {
     return (this.X*v.X) + (this.Y*v.Y) + (this.Z*v.Z);
 }
Esempio n. 28
0
 /// <summary>
 /// Computes whether or not this vector is perpendicular to another vector using the dot product method and
 /// comparing it to within a specified tolerance
 /// </summary>
 /// <param name="othervector"></param>
 /// <param name="tolerance"></param>
 /// <returns>true if the vector dot product is within the given tolerance of zero, false if not</returns>
 public bool IsPerpendicularTo(UnitVector3D othervector, double tolerance = 1e-6)
 {
     var @this = this.Normalize();
     return Math.Abs(@this.DotProduct(othervector)) < tolerance;
 }
Esempio n. 29
0
 /// <summary>
 /// Determine whether or not this vector is parallel to a unit vector within a given angle tolerance.
 /// </summary>
 /// <param name="othervector"></param>
 /// <param name="angleTolerance"></param>
 /// <returns>true if the vectors are parallel within the angle tolerance, false if they are not</returns>
 public bool IsParallelTo(UnitVector3D othervector, Angle angleTolerance)
 {
     var @this = this.Normalize();
     return @this.IsParallelTo(othervector, angleTolerance);
 }
Esempio n. 30
0
 /// <summary>
 /// Computes whether or not this vector is parallel to a unit vector using the dot product method and comparing it
 /// to within a specified tolerance.
 /// </summary>
 /// <param name="othervector"></param>
 /// <param name="tolerance">A tolerance value for the dot product method.  Values below 2*Precision.DoublePrecision may cause issues.</param>
 /// <returns>true if the vector dot product is within the given tolerance of unity, false if not</returns>
 public bool IsParallelTo(UnitVector3D othervector, double tolerance = 1e-10)
 {
     var @this = this.Normalize();
     return @this.IsParallelTo(othervector, tolerance);
 }