/// <summary> /// Test if this AxisAngle is approximately equal to another. /// </summary> /// <param name="other"></param> /// <returns></returns> public bool IsSimilar(AxisAngle other) { return(Math.Abs(this.Axis.X - other.Axis.X) < EPSILON2 && Math.Abs(this.Axis.Y - other.Axis.Y) < EPSILON2 && Math.Abs(this.Axis.Z - other.Axis.Z) < EPSILON2 && Math.Abs(this.Angle - other.Angle) < EPSILON2); }
/// <summary> /// Is this rotation equivalent to a given one? /// Equivalence is defined as rotations around vectors sharing the same axis (including opposite directions) /// and an angle with the same modulated equivalence. This in turn means the same spatial orientation after transformation. /// For example, the following rotations are equivalent: /// [0, 0, 1, 315] /// [0, 0, 1, 675] (one additional turn, same angle) /// [0, 0, 1, -45] (negative rotation, same angle) /// [0, 0, -1, 45] (flipped axis, same angle) /// [0, 0, 10, 315] (same axis and angle, longer vector. note non-unit vectors are not allowed in this AA representation) /// /// Also, these are equivalent: /// [0, 0, 0, 0] /// [0, 0, 1, 720] /// </summary> /// <param name="other"></param> /// <returns></returns> public bool IsEquivalent(AxisAngle other) { // Sanity checks if (this.IsZero()) { return(Math.Abs(other.Angle % 360) < EPSILON2); } else if (other.IsZero()) { return(Math.Abs(this.Angle % 360) < EPSILON2); } //Vector v1 = new Vector(this.X, this.Y, this.Z), //v2 = new Vector(axisAngle.X, axisAngle.Y, axisAngle.Z); //int directions = Vector.CompareDirections(v1, v2); int directions = Vector.CompareDirections(this, other); // If axes are not parallel, they are not equivalent if (directions == 0 || directions == 2) { return(false); } // Bring all angles to [0, 360] double a1 = this.Angle; while (a1 < 0) { a1 += 360; } a1 %= 360; if (Math.Abs(a1 - 360) < EPSILON2) { a1 = 0; } double a2 = other.Angle; while (a2 < 0) { a2 += 360; } a2 %= 360; if (Math.Abs(a2 - 360) < EPSILON2) { a2 = 0; } // If the vectors have the same direction, angles should be module of each other. if (directions == 1) { return(Math.Abs(a1 - a2) < EPSILON2); } // If opposite directions, they should add up to 360 degs. if (directions == 3) { return(Math.Abs(a1 + a2 - 360) < EPSILON2); } return(false); // if here, something went wrong }
/// <summary> /// Creates an AxisAngle as a shallow copy of another one. /// Internal constructor to bypass normalization. /// </summary> /// <param name="aa"></param> /// <param name="normalize"></param> internal AxisAngle(AxisAngle aa, bool normalize) : this(aa.X, aa.Y, aa.Z, aa.Angle, normalize) { }
/// <summary> /// Creates an AxisAngle as a shallow copy of another one. /// The axis vector will be automatically normalized. /// </summary> /// <param name="axisAngle"></param> public AxisAngle(AxisAngle axisAngle) : this(axisAngle.X, axisAngle.Y, axisAngle.Z, axisAngle.Angle, true) { }
internal void UpdateAxisAngle() { this.AA = this.Q.ToAxisAngle(); }
/// <summary> /// Main internal constructor. /// </summary> /// <param name="axisX"></param> /// <param name="axisY"></param> /// <param name="axisZ"></param> /// <param name="angleDegrees"></param> /// <param name="normalize"></param> internal Rotation(double axisX, double axisY, double axisZ, double angleDegrees, bool normalize) { this.AA = new AxisAngle(axisX, axisY, axisZ, angleDegrees, normalize); this.UpdateQuaternion(); }
public bool Rotate(AxisAngle aa) { return(this.Rotate(aa.ToQuaternion())); }