/// <summary> /// /// </summary> /// <param name="point"></param> /// <returns></returns> public bool ContainsIncl(Vec3d point) { return(X.ContainsIncl(point.X) && Y.ContainsIncl(point.Y) && Z.ContainsIncl(point.Z)); }
/// <summary> /// Returns the area gradient of the given triangle with respect to each vertex /// https://www.cs.cmu.edu/~kmcrane/Projects/DDG/paper.pdf p 64 /// </summary> /// <param name="p0"></param> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="g0"></param> /// <param name="g1"></param> /// <param name="g2"></param> /// <returns></returns> public static void GetTriAreaGradients(Vec3d p0, Vec3d p1, Vec3d p2, out Vec3d g0, out Vec3d g1, out Vec3d g2) { var d0 = p1 - p0; var d1 = p2 - p1; var d2 = p0 - p2; var n = Vec3d.Cross(d0, d1); n.Unitize(); g0 = Vec3d.Cross(n, d1) * 0.5; g1 = Vec3d.Cross(n, d2) * 0.5; g2 = g0 + g1; }
/// <summary> /// Returns the shortest vector from line a to line b. /// http://geomalgorithms.com/a07-_distance.html /// </summary> /// <param name="startA"></param> /// <param name="endA"></param> /// <param name="startB"></param> /// <param name="endB"></param> /// <returns></returns> public static Vec3d LineLineShortestVector(Vec3d startA, Vec3d endA, Vec3d startB, Vec3d endB) { Vec3d u = endA - startA; Vec3d v = endB - startB; Vec3d w = startA - startB; LineLineClosestPoints(u, v, w, out double tu, out double tv); return(v * tv - u * tu - w); }
/// <summary> /// Assumes the given axes are orthonormal. /// </summary> /// <param name="vector"></param> /// <param name="xAxis"></param> /// <param name="yAxis"></param> /// <returns></returns> public static double GetAngleInPlane(Vec3d vector, Vec3d xAxis, Vec3d yAxis) { double t = Math.Atan2(Vec3d.Dot(vector, xAxis), Vec3d.Dot(vector, yAxis)); return((t < 0.0) ? t + SlurMath.TwoPI : t); // shift discontinuity to 0 }
/// <summary> /// /// </summary> /// <param name="point"></param> /// <param name="a"></param> /// <param name="b"></param> /// <param name="c"></param> /// <returns></returns> public static Vec3d GetBarycentric(Vec3d point, Vec3d a, Vec3d b, Vec3d c) { // TODO throw new NotImplementedException(); }
/// <summary> /// Projects a point to the given plane along the given direction. /// </summary> /// <param name="point"></param> /// <param name="direction"></param> /// <param name="origin"></param> /// <param name="normal"></param> /// <returns></returns> public static Vec3d ProjectToPlaneAlong(Vec3d point, Vec3d origin, Vec3d normal, Vec3d direction) { return(point + Vec3d.MatchProjection(direction, origin - point, normal)); }
/// <summary> /// http://www.block.arch.ethz.ch/brg/files/2013-ijss-vanmele-shaping-tension-structures-with-actively-bent-linear-elements_1386929572.pdf /// </summary> /// <param name="v0"></param> /// <param name="v1"></param> /// <returns></returns> public static Vec3d GetCurvatureVector(Vec3d v0, Vec3d v1) { Vec3d v2 = Vec3d.Cross(v0, v1); return(Vec3d.Cross((v0.SquareLength * v1 - v1.SquareLength * v0), v2) / (2.0 * v2.SquareLength)); }
/// <summary> /// Assumes the given vectors are orthonormal. /// </summary> /// <param name="y"></param> /// <param name="z"></param> private void SetYZ(Vec3d y, Vec3d z) { _x = Vec3d.Cross(y, z); _y = y; _z = z; }
/// <summary> /// Assumes the given vectors are orthonormal. /// </summary> /// <param name="z"></param> /// <param name="x"></param> private void SetZX(Vec3d z, Vec3d x) { _x = x; _y = Vec3d.Cross(z, x); _z = z; }
/// <summary> /// /// </summary> public OrthoBasis3d(Vec3d x, Vec3d y) : this() { Set(x, y); }
/// <summary> /// Assumes the given vectors are orthonormal. /// </summary> /// <param name="x"></param> /// <param name="y"></param> private void SetXY(Vec3d x, Vec3d y) { _x = x; _y = y; _z = Vec3d.Cross(x, y); }
/// <summary> /// /// </summary> /// <param name="point"></param> public void Include(Vec3d point) { X.Include(point.X); Y.Include(point.Y); Z.Include(point.Z); }
/// <summary> /// /// </summary> /// <param name="delta"></param> public void Expand(Vec3d delta) { X.Expand(delta.X); Y.Expand(delta.Y); Z.Expand(delta.Z); }
/// <summary> /// /// </summary> /// <param name="delta"></param> public void Translate(Vec3d delta) { X.Translate(delta.X); Y.Translate(delta.Y); Z.Translate(delta.Z); }
/// <summary> /// /// </summary> /// <param name="point"></param> /// <param name="origin"></param> /// <param name="normal"></param> /// <returns></returns> public static Vec3d ProjectToPlane(Vec3d point, Vec3d origin, Vec3d normal) { return(point + Vec3d.Project(origin - point, normal)); }
/// <summary> /// Applies this rotation to the given vector. /// </summary> /// <param name="vector"></param> /// <returns></returns> public Vec3d Apply(Vec3d vector) { return(vector.X * _x + vector.Y * _y + vector.Z * _z); }
/// <summary> /// Projects a vector to the given plane along the given direction. /// </summary> /// <param name="vector"></param> /// <param name="normal"></param> /// <param name="direction"></param> /// <returns></returns> public static Vec3d ProjectToPlaneAlong(Vec3d vector, Vec3d normal, Vec3d direction) { return(vector - Vec3d.MatchProjection(direction, vector, normal)); }
/// <summary> /// Applies the inverse of this rotation to the given vector. /// </summary> /// <param name="vector"></param> /// <returns></returns> public Vec3d ApplyInverse(Vec3d vector) { return(new Vec3d(Vec3d.Dot(vector, _x), Vec3d.Dot(vector, _y), Vec3d.Dot(vector, _z))); }
/// <summary> /// Returns the center of the circle that passes through the 3 given points. /// </summary> /// <param name="p0"></param> /// <param name="p1"></param> /// <param name="p2"></param> /// <returns></returns> public static Vec3d GetCurvatureCenter(Vec3d p0, Vec3d p1, Vec3d p2) { return(p1 + GetCurvatureVector(p0 - p1, p2 - p1)); }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="z"></param> public void Deconstruct(out Vec3d x, out Vec3d y, out Vec3d z) { x = X; y = Y; z = Z; }
/// <summary> /// /// </summary> /// <param name="p0"></param> /// <param name="p1"></param> /// <param name="p2"></param> /// <returns></returns> public static Vec3d GetCircumcenter(Vec3d p0, Vec3d p1, Vec3d p2) { return(p0 + GetCurvatureVector(p1 - p0, p2 - p0)); }
/// <summary> /// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/ /// </summary> /// <param name="direction"></param> /// <param name=""></param> /// <returns></returns> public static Quaterniond CreateLookAt(Vec3d direction, Vec3d up) { throw new NotImplementedException(); }
/// <summary> /// Returns parameters for the closest pair of points between lines a and b. /// http://geomalgorithms.com/a07-_distance.html /// </summary> /// <param name="startA"></param> /// <param name="endA"></param> /// <param name="startB"></param> /// <param name="endB"></param> /// <param name="ta"></param> /// <param name="tb"></param> public static void LineLineClosestPoints(Vec3d startA, Vec3d endA, Vec3d startB, Vec3d endB, out double ta, out double tb) { LineLineClosestPoints(endA - startA, endB - startB, startA - startB, out ta, out tb); }
/// <summary> /// /// </summary> /// <param name="axis"></param> /// <param name="angle"></param> public Quaterniond(Vec3d axis, double angle) : this() { Set(axis, angle); }
/// <summary> /// /// </summary> /// <param name="point"></param> /// <param name="a"></param> /// <param name="b"></param> /// <param name="c"></param> /// <returns></returns> public static bool IsInTriangle(Vec3d point, Vec3d a, Vec3d b, Vec3d c) { // TODO throw new NotImplementedException(); }
/// <summary> /// The axis and angle of rotation are taken from the direction and length of the given vector respectively. /// </summary> /// <param name="rotation"></param> public Quaterniond(Vec3d rotation) : this() { Set(rotation); }
/// <summary> /// /// </summary> /// <param name="startA"></param> /// <param name="deltaA"></param> /// <param name="startB"></param> /// <param name="deltaB"></param> /// <param name="ta"></param> /// <param name="tb"></param> public static void LineLineClosestPoints2(Vec3d startA, Vec3d deltaA, Vec3d startB, Vec3d deltaB, out double ta, out double tb) { LineLineClosestPoints(deltaA, deltaB, startA - startB, out ta, out tb); }
/// <summary> /// /// </summary> /// <param name="point"></param> /// <param name="origin"></param> /// <param name="normal"></param> /// <returns></returns> public static Vec3d ReflectInPlane(Vec3d point, Vec3d origin, Vec3d normal) { return(point + Vec3d.Project(origin - point, normal) * 2.0); }
/// <summary> /// /// </summary> /// <param name="startA"></param> /// <param name="deltaA"></param> /// <param name="startB"></param> /// <param name="deltaB"></param> /// <returns></returns> public static Vec3d LineLineShortestVector2(Vec3d startA, Vec3d deltaA, Vec3d startB, Vec3d deltaB) { Vec3d w = startA - startB; LineLineClosestPoints(deltaA, deltaB, w, out double tu, out double tv); return(deltaB * tv - deltaA * tu - w); }
/// <summary> /// /// </summary> /// <param name="center"></param> /// <param name="offsetX"></param> /// <param name="offsetY"></param> /// <param name="offsetZ"></param> public Domain3d(Vec3d center, double offsetX, double offsetY, double offsetZ) { X = new Domain1d(center.X - offsetX, center.X + offsetX); Y = new Domain1d(center.Y - offsetY, center.Y + offsetY); Z = new Domain1d(center.Z - offsetZ, center.Z + offsetZ); }