/// <summary> /// use to combine bounds /// if i=0 take minimum otherwise maximum /// </summary> /// <param name="other">vector to combine with</param> /// <param name="i">if i=0 take minimum otherwise maximum</param> public void bounds(vector3D other, int i) { if (i == 0) { // take minimum if (other.x < x) { x = other.x; } if (other.y < y) { y = other.y; } if (other.z < z) { z = other.z; } } else { // take maximum if (other.x > x) { x = other.x; } if (other.y > y) { y = other.y; } if (other.z > z) { z = other.z; } } }
/// <summary> /// return square of distance from end of this vector to end of other /// </summary> /// <param name="other">calcules distance from this vector</param> /// <returns>square of distance from end of this vector to end of other</returns> public double distanceSquared(vector3D other) { double x1 = other.x - x; double y1 = other.y - y; double z1 = other.z - z; return(x1 * x1 + y1 * y1 + z1 * z1); }
/// <summary> /// subtract other vector from this /// for theory see: /// http://www.euclideanspace.com/maths/algebra/vectors/index.htm /// </summary> /// <param name="other">vector to be subtracted from this</param> public void sub(vector3D other) { if (other == null) { return; } x -= other.x; y -= other.y; z -= other.z; }
/// <summary> /// add other vector to this /// for theory see: /// http://www.euclideanspace.com/maths/algebra/vectors/index.htm /// </summary> /// <param name="other">vector to be added to this</param> public void add(vector3D other) { if (other == null) { return; } x += other.x; y += other.y; z += other.z; }
/// <summary> /// cross product /// for theory see: /// http://www.euclideanspace.com/maths/algebra/vectors/index.htm /// </summary> /// <param name="other">other vector to take cross product with</param> public void cross(vector3D other) { double xh = y * other.z - other.y * z; double yh = z * other.x - other.z * x; double zh = x * other.y - other.x * y; x = xh; y = yh; z = zh; }
/// <summary> /// set the value of this instance to the value of other /// this can be used to reuse an instance without the overheads of garbidge collection /// </summary> /// <param name="other">instace we want to use value of, if null then set to zero</param> public void copy(vector3D other) { if (other == null) { x = y = z = 0; return; } x = other.x; y = other.y; z = other.z; }
/// <summary> /// calcultes new translation when combining translations /// /// Rt = Ra Rb /// Ct = Cb /// Tt = Ra (Cb + Tb - Ca) + Ca + Ta - Cb /// /// for theory: /// http://www.euclideanspace.com/maths/geometry/rotations/rotationAndTranslation/nonMatrix/index.htm /// </summary> /// <param name="ta">Ta = translation of transform a in absolute coordinates</param> /// <param name="ra">Ra = rotation function of transform a in absolute coordinates</param> /// <param name="ca">Ca = centre of rotation of transform a in absolute coordinates</param> /// <param name="tb">Tb = translation of transform b in coordinates of transform a</param> /// <param name="cb">Cb = centre of rotation of transform b in coordinates of transform a</param> /// <returns>Tt total offset</returns> public vector3D rotationOffset(vector3D ta, classRotation ra, vector3D ca, vector3D tb, vector3D cb) { vector3D result = new vector3D(cb); result.add(tb); result.sub(ca); if (ra != null) { ra.transform(result); } result.add(ca); result.add(ta); result.sub(cb); return(result); }
/// <summary> /// returns true if any dimension of other vector is greater than the same dimension /// of this /// </summary> /// <param name="other">vector to compare with this</param> /// <returns>true if greater</returns> public bool greaterThan(vector3D other) { if (other.x > x) { return(true); } if (other.y > y) { return(true); } if (other.z > z) { return(true); } return(false); }
/// <summary> /// returns true if any dimension of other vector is less than the same dimension /// of this /// </summary> /// <param name="other">vector to compare with this</param> /// <returns>true if less</returns> public bool lessThan(vector3D other) { if (other.x < x) { return(true); } if (other.y < y) { return(true); } if (other.z < z) { return(true); } return(false); }
/// <summary> /// returns true if this vector has an equal value to other vector /// </summary> /// <param name="v2"></param> /// <returns></returns> public bool Equals(vector3D other) { if (other == null) { return(false); } if (x != other.x) { return(false); } if (y != other.y) { return(false); } if (z != other.z) { return(false); } return(true); }
/// <summary> /// calculates the effect of this rotation on a point /// the new point is given by=q * P1 * q' /// this version does not alter P1 but returns the result. /// /// for theory see: /// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm /// </summary> /// <param name="point">point to be transformed</param> /// <returns>translated point</returns> public vector3D getTransform(vector3D p1) { double wh = angle; double xh = x; double yh = y; double zh = z; if (coding == (int)cde.CODING_AXISANGLE) { double s = Math.Sin(angle / 2); xh = x * s; yh = y * s; zh = z * s; wh = Math.Cos(angle / 2); } vector3D p2 = new vector3D(); p2.x = wh * wh * p1.x + 2 * yh * wh * p1.z - 2 * zh * wh * p1.y + xh * xh * p1.x + 2 * yh * xh * p1.y + 2 * zh * xh * p1.z - zh * zh * p1.x - yh * yh * p1.x; p2.y = 2 * xh * yh * p1.x + yh * yh * p1.y + 2 * zh * yh * p1.z + 2 * wh * zh * p1.x - zh * zh * p1.y + wh * wh * p1.y - 2 * xh * wh * p1.z - xh * xh * p1.y; p2.z = 2 * xh * zh * p1.x + 2 * yh * zh * p1.y + zh * zh * p1.z - 2 * wh * yh * p1.x - yh * yh * p1.z + 2 * wh * xh * p1.y - xh * xh * p1.z + wh * wh * p1.z; return(p2); }
/// <summary> /// calculates the effect of this rotation on a point /// the new point is given by=q * P1 * q' /// this version returns the result in p1 /// /// for theory see: /// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm /// </summary> /// <param name="point">point to be transformed</param> public void transform(vector3D p1) { double wh = angle; double xh = x; double yh = y; double zh = z; if (coding == (int)cde.CODING_AXISANGLE) { double s = Math.Sin(angle / 2); xh = x * s; yh = y * s; zh = z * s; wh = Math.Cos(angle / 2); } double resultx = wh * wh * p1.x + 2 * yh * wh * p1.z - 2 * zh * wh * p1.y + xh * xh * p1.x + 2 * yh * xh * p1.y + 2 * zh * xh * p1.z - zh * zh * p1.x - yh * yh * p1.x; //double resulty = 2 * xh * yh * p1.x + yh * yh * p1.y + 2 * zh * yh * p1.z + 2 * wh * zh * p1.x - zh * zh * p1.y + wh * wh * p1.y - 2 * xh * wh * p1.z - xh * xh * p1.y; //double resultz = 2 * xh * zh * p1.x + 2 * yh * zh * p1.y + zh * zh * p1.z - 2 * wh * yh * p1.x - yh * yh * p1.z + 2 * wh * xh * p1.y - xh * xh * p1.z + wh * wh * p1.z; p1.x = resultx; p1.y = resultx; p1.z = resultx; }
/// <summary> /// scale this vector by inverse of other /// </summary> /// <param name="other">scale value</param> public void scaleInv(vector3D other) { x /= other.x; y /= other.y; z /= other.z; }
/// <summary> /// return square of distance from end of this vector to end of other /// </summary> /// <param name="other">calcules distance from this vector</param> /// <returns>square of distance from end of this vector to end of other</returns> public double distanceSquared(vector3D other) { double x1 = other.x - x; double y1 = other.y - y; double z1 = other.z - z; return x1 * x1 + y1 * y1 + z1 * z1; }
/// <summary> /// dot product /// for theory see: /// http://www.euclideanspace.com/maths/algebra/vectors/index.htm /// </summary> /// <param name="other">vector to take dot product with</param> /// <returns>dot product</returns> public double dot(vector3D other) { return((x * other.x) + (y * other.y) + (z * other.z)); }
/// <summary> /// subtract other vector from this /// for theory see: /// http://www.euclideanspace.com/maths/algebra/vectors/index.htm /// </summary> /// <param name="other">vector to be subtracted from this</param> public void sub(vector3D other) { if (other == null) return; x -= other.x; y -= other.y; z -= other.z; }
/// <summary> /// use to combine bounds /// if i=0 take minimum otherwise maximum /// </summary> /// <param name="other">vector to combine with</param> /// <param name="i">if i=0 take minimum otherwise maximum</param> public void bounds(vector3D other, int i) { if (i == 0) { // take minimum if (other.x < x) x = other.x; if (other.y < y) y = other.y; if (other.z < z) z = other.z; } else { // take maximum if (other.x > x) x = other.x; if (other.y > y) y = other.y; if (other.z > z) z = other.z; } }
/// <summary> /// returns true if any dimension of other vector is less than the same dimension /// of this /// </summary> /// <param name="other">vector to compare with this</param> /// <returns>true if less</returns> public bool lessThan(vector3D other) { if (other.x < x) return true; if (other.y < y) return true; if (other.z < z) return true; return false; }
/// <summary> /// returns true if any dimension of other vector is greater than the same dimension /// of this /// </summary> /// <param name="other">vector to compare with this</param> /// <returns>true if greater</returns> public bool greaterThan(vector3D other) { if (other.x > x) return true; if (other.y > y) return true; if (other.z > z) return true; return false; }
/// <summary> /// copy constructor /// </summary> /// <param name="in1">set values to save value in1</param> public vector3D(vector3D in1) { x = (in1 != null) ? in1.x : 0; y = (in1 != null) ? in1.y : 0; z = (in1 != null) ? in1.z : 1; }
/// <summary> /// returns true if this vector has an equal value to other vector /// </summary> /// <param name="v2"></param> /// <returns></returns> public bool Equals(vector3D other) { if (other == null) return false; if (x != other.x) return false; if (y != other.y) return false; if (z != other.z) return false; return true; }
/// <summary> /// calculates the effect of this rotation on a point /// the new point is given by=q * P1 * q' /// this version returns the result in p1 /// /// for theory see: /// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm /// </summary> /// <param name="point">point to be transformed</param> public void transform(vector3D p1) { double wh = angle; double xh = x; double yh = y; double zh = z; if (coding == (int)cde.CODING_AXISANGLE) { double s = Math.Sin(angle / 2); xh = x * s; yh = y * s; zh = z * s; wh = Math.Cos(angle / 2); } double resultx = wh * wh * p1.x + 2 * yh * wh * p1.z - 2 * zh * wh * p1.y + xh * xh * p1.x + 2 * yh * xh * p1.y + 2 * zh * xh * p1.z - zh * zh * p1.x - yh * yh * p1.x; double resulty = 2 * xh * yh * p1.x + yh * yh * p1.y + 2 * zh * yh * p1.z + 2 * wh * zh * p1.x - zh * zh * p1.y + wh * wh * p1.y - 2 * xh * wh * p1.z - xh * xh * p1.y; double resultz = 2 * xh * zh * p1.x + 2 * yh * zh * p1.y + zh * zh * p1.z - 2 * wh * yh * p1.x - yh * yh * p1.z + 2 * wh * xh * p1.y - xh * xh * p1.z + wh * wh * p1.z; p1.x = resultx; p1.y = resultx; p1.z = resultx; }
/// <summary> /// calculates the effect of this rotation on a point /// the new point is given by=q * P1 * q' /// this version does not alter P1 but returns the result. /// /// for theory see: /// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/index.htm /// </summary> /// <param name="point">point to be transformed</param> /// <returns>translated point</returns> public vector3D getTransform(vector3D p1) { double wh = angle; double xh = x; double yh = y; double zh = z; if (coding == (int)cde.CODING_AXISANGLE) { double s = Math.Sin(angle / 2); xh = x * s; yh = y * s; zh = z * s; wh = Math.Cos(angle / 2); } vector3D p2 = new vector3D(); p2.x = wh * wh * p1.x + 2 * yh * wh * p1.z - 2 * zh * wh * p1.y + xh * xh * p1.x + 2 * yh * xh * p1.y + 2 * zh * xh * p1.z - zh * zh * p1.x - yh * yh * p1.x; p2.y = 2 * xh * yh * p1.x + yh * yh * p1.y + 2 * zh * yh * p1.z + 2 * wh * zh * p1.x - zh * zh * p1.y + wh * wh * p1.y - 2 * xh * wh * p1.z - xh * xh * p1.y; p2.z = 2 * xh * zh * p1.x + 2 * yh * zh * p1.y + zh * zh * p1.z - 2 * wh * yh * p1.x - yh * yh * p1.z + 2 * wh * xh * p1.y - xh * xh * p1.z + wh * wh * p1.z; return p2; }
/// <summary> /// scale this vector posibly different in x,y and z directions /// </summary> /// <param name="other">scale value</param> public void scale(vector3D other) { x *= other.x; y *= other.y; z *= other.z; }
/// <summary> /// dot product /// for theory see: /// http://www.euclideanspace.com/maths/algebra/vectors/index.htm /// </summary> /// <param name="other">vector to take dot product with</param> /// <returns>dot product</returns> public double dot(vector3D other) { return (x * other.x) + (y * other.y) + (z * other.z); }
/// <summary> /// add other vector to this /// for theory see: /// http://www.euclideanspace.com/maths/algebra/vectors/index.htm /// </summary> /// <param name="other">vector to be added to this</param> public void add(vector3D other) { if (other == null) return; x += other.x; y += other.y; z += other.z; }
/// <summary> /// calcultes new translation when combining translations /// /// Rt = Ra Rb /// Ct = Cb /// Tt = Ra (Cb + Tb - Ca) + Ca + Ta - Cb /// /// for theory: /// http://www.euclideanspace.com/maths/geometry/rotations/rotationAndTranslation/nonMatrix/index.htm /// </summary> /// <param name="ta">Ta = translation of transform a in absolute coordinates</param> /// <param name="ra">Ra = rotation function of transform a in absolute coordinates</param> /// <param name="ca">Ca = centre of rotation of transform a in absolute coordinates</param> /// <param name="tb">Tb = translation of transform b in coordinates of transform a</param> /// <param name="cb">Cb = centre of rotation of transform b in coordinates of transform a</param> /// <returns>Tt total offset</returns> public vector3D rotationOffset(vector3D ta, classRotation ra, vector3D ca, vector3D tb, vector3D cb) { vector3D result = new vector3D(cb); result.add(tb); result.sub(ca); if (ra != null) ra.transform(result); result.add(ca); result.add(ta); result.sub(cb); return result; }
/// <summary> /// static method to return sum of two vectors /// </summary> /// <param name="a">first vector to be added</param> /// <param name="b">second vector to be added</param> /// <returns>the sum</returns> public static vector3D add(vector3D a, vector3D b) { return new vector3D(a.x + b.x, a.y + b.y, a.z + b.z); }
/// <summary> /// static method to return difference of two vectors /// </summary> /// <param name="a">first vector</param> /// <param name="b">subract this vector</param> /// <returns>result</returns> public static vector3D sub(vector3D a, vector3D b) { return(new vector3D(a.x - b.x, a.y - b.y, a.z - b.z)); }
/// <summary> /// static method to return sum of two vectors /// </summary> /// <param name="a">first vector to be added</param> /// <param name="b">second vector to be added</param> /// <returns>the sum</returns> public static vector3D add(vector3D a, vector3D b) { return(new vector3D(a.x + b.x, a.y + b.y, a.z + b.z)); }
/// <summary> /// static method to return difference of two vectors /// </summary> /// <param name="a">first vector</param> /// <param name="b">subract this vector</param> /// <returns>result</returns> public static vector3D sub(vector3D a, vector3D b) { return new vector3D(a.x - b.x, a.y - b.y, a.z - b.z); }