/// <summary> /// Create a transform by origin, X, Y, and Z axes. Axes are automatically unitized — to create non-uniform transforms, use Transform.Scale. /// </summary> /// <param name="origin">The origin of the transform.</param> /// <param name="xAxis">The X axis of the transform.</param> /// <param name="yAxis">The Y axis of the transform.</param> /// <param name="zAxis">The Z axis of the transform.</param> public Transform(Vector3 origin, Vector3 xAxis, Vector3 yAxis, Vector3 zAxis) { this.Matrix = new Matrix(xAxis.Unitized(), yAxis.Unitized(), zAxis.Unitized(), origin); }
/// <summary> /// Create a transform by origin and X and Z axes. /// </summary> /// <param name="origin">The origin of the transform.</param> /// <param name="xAxis">The X axis of the transform.</param> /// <param name="zAxis">The Z axis of the transform.</param> /// <param name="rotation">An optional rotation in degrees around the transform's z axis.</param> public Transform(Vector3 origin, Vector3 xAxis, Vector3 zAxis, double rotation = 0.0) { var x = xAxis.Unitized(); var z = zAxis.Unitized(); var y = z.Cross(x).Unitized(); this.Matrix = new Matrix(x, y, z, Vector3.Origin); ApplyRotationAndTranslation(rotation, z, origin); }
/// <summary> /// Compute the 2D convex hull of a set of 3D points in a plane. /// </summary> /// <param name="points">A collection of points</param> /// <param name="planeNormal">The normal direction of the plane in which to compute the hull.</param> /// <returns>A polygon representing the convex hull, projected along the normal vector to the average depth of the provided points.</returns> public static Polygon FromPointsInPlane(IEnumerable <Vector3> points, Vector3 planeNormal) { if (planeNormal.Length().ApproximatelyEquals(0)) { throw new ArgumentException("The current normal vector cannot be of length 0"); } if (planeNormal.Unitized() == Vector3.ZAxis || planeNormal.Unitized().Negate() == Vector3.ZAxis) { return(FromPoints(points)); } else { var center3D = points.Average(); var toOrientation = new Transform(center3D, planeNormal); var fromOrientation = toOrientation.Inverted(); var tPoints = points.Select(p => fromOrientation.OfPoint(p)).Select(p => new Vector3(p.X, p.Y)); var twoDHull = FromPoints(tPoints); return(twoDHull.TransformedPolygon(toOrientation)); } }
/// <summary> /// The normal of this polygon, according to Newell's Method. /// </summary> /// <returns>The unitized sum of the cross products of each pair of edges.</returns> public override Vector3 Normal() { var normal = new Vector3(); for (int i = 0; i < Vertices.Count; i++) { var p0 = Vertices[i]; var p1 = Vertices[(i + 1) % Vertices.Count]; normal.X += (p0.Y - p1.Y) * (p0.Z + p1.Z); normal.Y += (p0.Z - p1.Z) * (p0.X + p1.X); normal.Z += (p0.X - p1.X) * (p0.Y + p1.Y); } return(normal.Unitized()); }
/// <summary> /// Calculate the normal of the plane containing a set of points. /// </summary> /// <param name="points">The points in the plane.</param> /// <returns>The normal of the plane containing the points.</returns> internal static Vector3 NormalFromPlanarWoundPoints(this IList <Vector3> points) { var normal = new Vector3(); for (int i = 0; i < points.Count; i++) { var p0 = points[i]; var p1 = points[(i + 1) % points.Count]; normal.X += (p0.Y - p1.Y) * (p0.Z + p1.Z); normal.Y += (p0.Z - p1.Z) * (p0.X + p1.X); normal.Z += (p0.X - p1.X) * (p0.Y + p1.Y); } return(normal.Unitized()); }
/// <summary> /// The normal of this polyline, according to Newell's Method. /// </summary> /// <returns>The unitized sum of the cross products of each pair of edges.</returns> public virtual Vector3 Normal() { // This is a slight variation on Newell that does not // close the loop, as we do for polygons. For polylines, // closing the loop often results in self-intersection // which returns a zero length vector. var normal = new Vector3(); for (int i = 0; i < Vertices.Count - 1; i++) { var p0 = Vertices[i]; var p1 = Vertices[i + 1]; normal.X += (p0.Y - p1.Y) * (p0.Z + p1.Z); normal.Y += (p0.Z - p1.Z) * (p0.X + p1.X); normal.Z += (p0.X - p1.X) * (p0.Y + p1.Y); } return(normal.Unitized()); }
/// <summary> /// Construct a line of length from a start along direction. /// </summary> /// <param name="start"></param> /// <param name="direction"></param> /// <param name="length"></param> public Line(Vector3 start, Vector3 direction, double length) { this.Start = start; this.End = start + direction.Unitized() * length; }