public void interpolateDirection(double slon, double slat, double elon, double elat, double t, ref double lon, ref double lat) { Vector3D s = new Vector3D((Math.Cos(slon) * Math.Cos(slat)), (Math.Sin(slon) * Math.Cos(slat)), Math.Sin(slat)); Vector3D e = new Vector3D((Math.Cos(elon) * Math.Cos(elat)), (Math.Sin(elon) * Math.Cos(elat)), Math.Sin(elat)); Vector3D v = Vector3D.Add(s * (1d - t), e * t); v.Normalize(); lat = Math.Asin(v.Z); lon = Math.Atan2(v.Y, v.X); }
public static Vector3D fromLatLon(double lon, double lat) { Vector3D ret = new Vector3D(); var latRad = MathUtilD.DegreesToRadians(lat); var lonRad = MathUtilD.DegreesToRadians(lon); ret.X = 6359.99 * Math.Cos(latRad) * Math.Cos(lonRad); ret.Y = 6359.99 * Math.Sin(latRad); ret.Z = 6359.99 * Math.Cos(latRad) * Math.Sin(lonRad); return ret; }
public override void move(Vector3D oldP, Vector3D newP) { oldP.Normalize(); newP.Normalize(); double oldlat = Math.Asin(oldP.Y); // safe_asin(oldp.z); double oldlon = Math.Atan2(oldP.Z, oldP.X); // atan2(oldp.y, oldp.x); double lat = Math.Asin(newP.Y); double lon = Math.Atan2(newP.Y, newP.X); x0 -= lon - oldlon; y0 -= lat - oldlat; y0 = Math.Max(-Math.PI / 2.0, Math.Min(Math.PI / 2.0, y0)); }
public override void moveForward(double distance) { double co = Math.Cos(x0); // x0 = longitude double so = Math.Sin(x0); double ca = Math.Cos(y0); // y0 = latitude double sa = Math.Sin(y0); Vector3D po = new Vector3D(co * ca, so * ca, sa) * R; Vector3D px = new Vector3D(-so, co, 0.0); Vector3D py = new Vector3D(-co * sa, -so * sa, ca); Vector3D pd = (po - px * Math.Sin(phi) * distance + py * Math.Cos(phi) * distance); pd.Normalize(); x0 = Math.Atan2(pd.Z, pd.X); y0 = Math.Asin(pd.Y); }
public override double interpolate(double sx0, double sy0, double stheta, double sphi, double sd, double dx0, double dy0, double dtheta, double dphi, double dd, double t) { Vector3D s = new Vector3D(Math.Cos(sx0) * Math.Cos(sy0), Math.Sin(sx0) * Math.Cos(sy0), Math.Sin(sy0)); Vector3D e = new Vector3D(Math.Cos(dx0) * Math.Cos(dy0), Math.Sin(dx0) * Math.Cos(dy0), Math.Sin(dy0)); double dist = Math.Max(Math.Acos(Vector3D.Dot(s, e)) * R, 1e-3); t = Math.Min(t + Math.Min(0.1, 5000.0 / dist), 1.0); double T = 0.5 * Math.Atan(4.0 * (t - 0.5)) / Math.Atan(4.0 * 0.5) + 0.5; interpolateDirection(sx0, sy0, dx0, dy0, T, ref x0, ref y0); interpolateDirection(sphi, stheta, dphi, dtheta, T, ref phi, ref theta); double W = 10.0; d = sd * (1.0 - t) + dd * t + dist * (Math.Exp(-W * (t - 0.5) * (t - 0.5)) - Math.Exp(-W * 0.25)); return t; }
/// <summary> /// Creates a MatrixD that rotates around an arbitrary axis. /// </summary> /// <param name="axis">The axis around which to rotate. This parameter is assumed to be normalized.</param> /// <param name="angle">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.</param> /// <returns>The created rotation MatrixD.</returns> public static MatrixD RotationAxis(Vector3D axis, double angle) { MatrixD result; RotationAxis(ref axis, angle, out result); return result; }
/// <summary> /// Creates a MatrixD that rotates around an arbitrary axis. /// </summary> /// <param name="axis">The axis around which to rotate. This parameter is assumed to be normalized.</param> /// <param name="angle">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis toward the origin.</param> /// <param name="result">When the method completes, contains the created rotation MatrixD.</param> public static void RotationAxis(ref Vector3D axis, double angle, out MatrixD result) { double x = axis.X; double y = axis.Y; double z = axis.Z; double cos = (double)System.Math.Cos(angle); double sin = (double)System.Math.Sin(angle); double xx = x * x; double yy = y * y; double zz = z * z; double xy = x * y; double xz = x * z; double yz = y * z; result = MatrixD.Identity; result.M11 = xx + (cos * (1.0d - xx)); result.M12 = (xy - (cos * xy)) + (sin * z); result.M13 = (xz - (cos * xz)) - (sin * y); result.M21 = (xy - (cos * xy)) - (sin * z); result.M22 = yy + (cos * (1.0d - yy)); result.M23 = (yz - (cos * yz)) + (sin * x); result.M31 = (xz - (cos * xz)) + (sin * y); result.M32 = (yz - (cos * yz)) - (sin * x); result.M33 = zz + (cos * (1.0d - zz)); }
/// <summary> /// Performs a coordinate transformation using the given <see cref="SharpDX.Matrix"/>. /// </summary> /// <param name="coordinate">The coordinate vector to transform.</param> /// <param name="transform">The transformation <see cref="SharpDX.Matrix"/>.</param> /// <param name="result">When the method completes, contains the transformed coordinates.</param> /// <remarks> /// A coordinate transform performs the transformation with the assumption that the w component /// is one. The four dimensional vector obtained from the transformation operation has each /// component in the vector divided by the w component. This forces the w component to be one and /// therefore makes the vector homogeneous. The homogeneous vector is often preferred when working /// with coordinates as the w component can safely be ignored. /// </remarks> public static void TransformCoordinate(ref Vector3D coordinate, ref MatrixD transform, out Vector3D result) { Vector4D vector = new Vector4D(); vector.X = (coordinate.X * transform.M11) + (coordinate.Y * transform.M21) + (coordinate.Z * transform.M31) + transform.M41; vector.Y = (coordinate.X * transform.M12) + (coordinate.Y * transform.M22) + (coordinate.Z * transform.M32) + transform.M42; vector.Z = (coordinate.X * transform.M13) + (coordinate.Y * transform.M23) + (coordinate.Z * transform.M33) + transform.M43; vector.W = 1f / ((coordinate.X * transform.M14) + (coordinate.Y * transform.M24) + (coordinate.Z * transform.M34) + transform.M44); result = new Vector3D(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W); }
/// <summary> /// Creates a spherical billboard that rotates around a specified object position. /// </summary> /// <param name="objectPosition">The position of the object around which the billboard will rotate.</param> /// <param name="cameraPosition">The position of the camera.</param> /// <param name="cameraUpVector">The up vector of the camera.</param> /// <param name="cameraForwardVector">The forward vector of the camera.</param> /// <returns>The created billboard MatrixD.</returns> public static MatrixD Billboard(Vector3D objectPosition, Vector3D cameraPosition, Vector3D cameraUpVector, Vector3D cameraForwardVector) { MatrixD result; Billboard(ref objectPosition, ref cameraPosition, ref cameraUpVector, ref cameraForwardVector, out result); return result; }
/// <summary> /// Performs a normal transformation using the given <see cref="SharpDX.Matrix"/>. /// </summary> /// <param name="normal">The normal vector to transform.</param> /// <param name="transform">The transformation <see cref="SharpDX.Matrix"/>.</param> /// <param name="result">When the method completes, contains the transformed normal.</param> /// <remarks> /// A normal transform performs the transformation with the assumption that the w component /// is zero. This causes the fourth row and fourth column of the matrix to be unused. The /// end result is a vector that is not translated, but all other transformation properties /// apply. This is often preferred for normal vectors as normals purely represent direction /// rather than location because normal vectors should not be translated. /// </remarks> public static void TransformNormal(ref Vector3D normal, ref MatrixD transform, out Vector3D result) { result = new Vector3D( (normal.X * transform.M11) + (normal.Y * transform.M21) + (normal.Z * transform.M31), (normal.X * transform.M12) + (normal.Y * transform.M22) + (normal.Z * transform.M32), (normal.X * transform.M13) + (normal.Y * transform.M23) + (normal.Z * transform.M33)); }
/// <summary> /// Creates a transformation MatrixD. /// </summary> /// <param name="scalingCenter">Center point of the scaling operation.</param> /// <param name="scalingRotation">Scaling rotation amount.</param> /// <param name="scaling">Scaling factor.</param> /// <param name="rotationCenter">The center of the rotation.</param> /// <param name="rotation">The rotation of the transformation.</param> /// <param name="translation">The translation factor of the transformation.</param> /// <returns>The created transformation MatrixD.</returns> public static MatrixD Transformation(Vector3D scalingCenter, Quaternion scalingRotation, Vector3D scaling, Vector3D rotationCenter, Quaternion rotation, Vector3D translation) { MatrixD result; Transformation(ref scalingCenter, ref scalingRotation, ref scaling, ref rotationCenter, ref rotation, ref translation, out result); return result; }
/// <summary> /// Creates a skew/shear MatrixD by means of a translation vector, a rotation vector, and a rotation angle. /// shearing is performed in the direction of translation vector, where translation vector and rotation vector define the shearing plane. /// The effect is such that the skewed rotation vector has the specified angle with rotation itself. /// </summary> /// <param name="angle">The rotation angle.</param> /// <param name="rotationVec">The rotation vector</param> /// <param name="transVec">The translation vector</param> /// <param name="MatrixD">Contains the created skew/shear MatrixD. </param> public static void Skew(double angle, ref Vector3D rotationVec, ref Vector3D transVec, out MatrixD MatrixD) { //http://elckerlyc.ewi.utwente.nl/browser/Elckerlyc/Hmi/HmiMath/src/hmi/math/Mat3f.java double MINIMAL_SKEW_ANGLE = 0.000001f; Vector3D e0 = rotationVec; Vector3D e1 = Vector3D.Normalize(transVec); double rv1; Vector3D.Dot(ref rotationVec, ref e1, out rv1); e0 += rv1 * e1; double rv0; Vector3D.Dot(ref rotationVec, ref e0, out rv0); double cosa = (double)System.Math.Cos(angle); double sina = (double)System.Math.Sin(angle); double rr0 = rv0 * cosa - rv1 * sina; double rr1 = rv0 * sina + rv1 * cosa; if (rr0 < MINIMAL_SKEW_ANGLE) throw new ArgumentException("illegal skew angle"); double d = (rr1 / rr0) - (rv1 / rv0); MatrixD = MatrixD.Identity; MatrixD.M11 = d * e1[0] * e0[0] + 1.0f; MatrixD.M12 = d * e1[0] * e0[1]; MatrixD.M13 = d * e1[0] * e0[2]; MatrixD.M21 = d * e1[1] * e0[0]; MatrixD.M22 = d * e1[1] * e0[1] + 1.0f; MatrixD.M23 = d * e1[1] * e0[2]; MatrixD.M31 = d * e1[2] * e0[0]; MatrixD.M32 = d * e1[2] * e0[1]; MatrixD.M33 = d * e1[2] * e0[2] + 1.0f; }
public override void turn(double angle) { double co = Math.Cos(x0); // x0 = longitude double so = Math.Sin(x0); double ca = Math.Cos(y0); // y0 = latitude double sa = Math.Sin(y0); double l = d * Math.Sin(theta); Vector3D po = new Vector3D(co * ca, so * ca, sa) * R; Vector3D px = new Vector3D(-so, co, 0.0); Vector3D py = new Vector3D(-co * sa, -so * sa, ca); Vector3D f = -px * Math.Sin(phi) + py * Math.Cos(phi); Vector3D r = px * Math.Cos(phi) + py * Math.Sin(phi); Vector3D pd = (po + f * (Math.Cos(angle) - 1.0) * l - r * Math.Sin(angle) * l); pd.Normalize(); x0 = Math.Atan2(pd.Z, pd.X); y0 = Math.Asin(pd.Y); phi += angle; }
public override void update() { double co = Math.Cos(x0); // x0 = longitude double so = Math.Sin(x0); double ca = Math.Cos(y0); // y0 = latitude double sa = Math.Sin(y0); Vector3D po = new Vector3D(co*ca, so*ca, sa) * (R + groundHeight); Vector3D px = new Vector3D(-so, co, 0.0); Vector3D py = new Vector3D(-co*sa, -so*sa, ca); Vector3D pz = new Vector3D(co*ca, so*ca, sa); double ct = Math.Cos(theta); double st = Math.Sin(theta); double cp = Math.Cos(phi); double sp = Math.Sin(phi); Vector3D cx = px * cp + py * sp; Vector3D cy = -px * sp*ct + py * cp*ct + pz * st; Vector3D cz = px * sp*st - py * cp*st + pz * ct; position = po + cz * d * zoom; if (position.Length() < R + 0.5 + groundHeight) { position.Normalize(); position *= R + 0.5 + groundHeight; //position = position.normalize(R + 0.5 + groundHeight); } MatrixD view = new MatrixD(cx.X, cx.Y, cx.Z, 0.0, cy.X, cy.Y, cy.Z, 0.0, cz.X, cz.Y, cz.Z, 0.0, 0.0, 0.0, 0.0, 1.0); view = view * MatrixD.Translation(-position); node.Local = view; }
/// <summary> /// Performs a normal transformation on an array of vectors using the given <see cref="SharpDX.Matrix"/>. /// </summary> /// <param name="source">The array of normal vectors to transform.</param> /// <param name="transform">The transformation <see cref="SharpDX.Matrix"/>.</param> /// <param name="destination">The array for which the transformed vectors are stored. /// This array may be the same array as <paramref name="source"/>.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="source"/> or <paramref name="destination"/> is <c>null</c>.</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="destination"/> is shorter in length than <paramref name="source"/>.</exception> /// <remarks> /// A normal transform performs the transformation with the assumption that the w component /// is zero. This causes the fourth row and fourth column of the matrix to be unused. The /// end result is a vector that is not translated, but all other transformation properties /// apply. This is often preferred for normal vectors as normals purely represent direction /// rather than location because normal vectors should not be translated. /// </remarks> public static void TransformNormal(Vector3D[] source, ref MatrixD transform, Vector3D[] destination) { if (source == null) throw new ArgumentNullException("source"); if (destination == null) throw new ArgumentNullException("destination"); if (destination.Length < source.Length) throw new ArgumentOutOfRangeException("destination", "The destination array must be of same length or larger length than the source array."); for (int i = 0; i < source.Length; ++i) { TransformNormal(ref source[i], ref transform, out destination[i]); } }
/// <summary> /// Performs a normal transformation using the given <see cref="SharpDX.Matrix"/>. /// </summary> /// <param name="normal">The normal vector to transform.</param> /// <param name="transform">The transformation <see cref="SharpDX.Matrix"/>.</param> /// <returns>The transformed normal.</returns> /// <remarks> /// A normal transform performs the transformation with the assumption that the w component /// is zero. This causes the fourth row and fourth column of the matrix to be unused. The /// end result is a vector that is not translated, but all other transformation properties /// apply. This is often preferred for normal vectors as normals purely represent direction /// rather than location because normal vectors should not be translated. /// </remarks> public static Vector3D TransformNormal(Vector3D normal, MatrixD transform) { Vector3D result; TransformNormal(ref normal, ref transform, out result); return result; }
/// <summary> /// Creates a MatrixD that scales along the x-axis, y-axis, and y-axis. /// </summary> /// <param name="scale">Scaling factor for all three axes.</param> /// <param name="result">When the method completes, contains the created scaling MatrixD.</param> public static void Scaling(ref Vector3D scale, out MatrixD result) { Scaling(scale.X, scale.Y, scale.Z, out result); }
public virtual void update() { Vector3D po = new Vector3D(x0, y0, groundHeight); Vector3D px = new Vector3D(1.0, 0.0, 0.0); Vector3D py = new Vector3D(0.0, 1.0, 0.0); Vector3D pz = new Vector3D(0.0, 0.0, 1.0); double ct = Math.Cos(theta); double st = Math.Sin(theta); double cp = Math.Cos(phi); double sp = Math.Sin(phi); Vector3D cx = px * cp + py * sp; Vector3D cy = -px * sp * ct + py * cp * ct + pz * st; Vector3D cz = px * sp * st - py * cp * st + pz * ct; position = po + cz * d * zoom; if (position.Z < groundHeight + 1.0) { position.Z = groundHeight + 1.0; } MatrixD view = new MatrixD(cx.X, cx.Y, cx.Z, 0.0, cy.X, cy.Y, cy.Z, 0.0, cz.X, cz.Y, cz.Z, 0.0, 0.0, 0.0, 0.0, 1.0); view = view * MatrixD.Translation(-position); node.Local = view; }
/// <summary> /// Creates a MatrixD that scales along the x-axis, y-axis, and y-axis. /// </summary> /// <param name="scale">Scaling factor for all three axes.</param> /// <returns>The created scaling MatrixD.</returns> public static MatrixD Scaling(Vector3D scale) { MatrixD result; Scaling(ref scale, out result); return result; }
/// <summary> /// Creates a translation MatrixD using the specified offsets. /// </summary> /// <param name="value">The offset for all three coordinate planes.</param> /// <returns>The created translation MatrixD.</returns> public static MatrixD Translation(Vector3D value) { MatrixD result; Translation(ref value, out result); return result; }
/// <summary> /// Creates a transformation MatrixD. /// </summary> /// <param name="scalingCenter">Center point of the scaling operation.</param> /// <param name="scalingRotation">Scaling rotation amount.</param> /// <param name="scaling">Scaling factor.</param> /// <param name="rotationCenter">The center of the rotation.</param> /// <param name="rotation">The rotation of the transformation.</param> /// <param name="translation">The translation factor of the transformation.</param> /// <param name="result">When the method completes, contains the created transformation MatrixD.</param> public static void Transformation(ref Vector3D scalingCenter, ref Quaternion scalingRotation, ref Vector3D scaling, ref Vector3D rotationCenter, ref Quaternion rotation, ref Vector3D translation, out MatrixD result) { MatrixD sr = RotationQuaternion(scalingRotation); result = Translation(-scalingCenter) * Transpose(sr) * Scaling(scaling) * sr * Translation(scalingCenter) * Translation(-rotationCenter) * RotationQuaternion(rotation) * Translation(rotationCenter) * Translation(translation); }
/// <summary> /// Creates a 3D affine transformation MatrixD. /// </summary> /// <param name="scaling">Scaling factor.</param> /// <param name="rotationCenter">The center of the rotation.</param> /// <param name="rotation">The rotation of the transformation.</param> /// <param name="translation">The translation factor of the transformation.</param> /// <returns>The created affine transformation MatrixD.</returns> public static MatrixD AffineTransformation(double scaling, Vector3D rotationCenter, Quaternion rotation, Vector3D translation) { MatrixD result; AffineTransformation(scaling, ref rotationCenter, ref rotation, ref translation, out result); return result; }
/// <summary> /// Creates a translation MatrixD using the specified offsets. /// </summary> /// <param name="value">The offset for all three coordinate planes.</param> /// <param name="result">When the method completes, contains the created translation MatrixD.</param> public static void Translation(ref Vector3D value, out MatrixD result) { Translation(value.X, value.Y, value.Z, out result); }
/// <summary> /// Performs a coordinate transformation using the given <see cref="SharpDX.Matrix"/>. /// </summary> /// <param name="coordinate">The coordinate vector to transform.</param> /// <param name="transform">The transformation <see cref="SharpDX.Matrix"/>.</param> /// <returns>The transformed coordinates.</returns> /// <remarks> /// A coordinate transform performs the transformation with the assumption that the w component /// is one. The four dimensional vector obtained from the transformation operation has each /// component in the vector divided by the w component. This forces the w component to be one and /// therefore makes the vector homogeneous. The homogeneous vector is often preferred when working /// with coordinates as the w component can safely be ignored. /// </remarks> public static Vector3D TransformCoordinate(Vector3D coordinate, MatrixD transform) { Vector3D result; TransformCoordinate(ref coordinate, ref transform, out result); return result; }
/// <summary> /// Creates a 3D affine transformation MatrixD. /// </summary> /// <param name="scaling">Scaling factor.</param> /// <param name="rotationCenter">The center of the rotation.</param> /// <param name="rotation">The rotation of the transformation.</param> /// <param name="translation">The translation factor of the transformation.</param> /// <param name="result">When the method completes, contains the created affine transformation MatrixD.</param> public static void AffineTransformation(double scaling, ref Vector3D rotationCenter, ref Quaternion rotation, ref Vector3D translation, out MatrixD result) { result = Scaling(scaling) * Translation(-rotationCenter) * RotationQuaternion(rotation) * Translation(rotationCenter) * Translation(translation); }
public virtual void move(Vector3D oldP, Vector3D newP) { x0 -= newP.X - oldP.X; y0 -= newP.Y - oldP.Y; }
/// <summary> /// Creates a spherical billboard that rotates around a specified object position. /// </summary> /// <param name="objectPosition">The position of the object around which the billboard will rotate.</param> /// <param name="cameraPosition">The position of the camera.</param> /// <param name="cameraUpVector">The up vector of the camera.</param> /// <param name="cameraForwardVector">The forward vector of the camera.</param> /// <param name="result">When the method completes, contains the created billboard MatrixD.</param> public static void Billboard(ref Vector3D objectPosition, ref Vector3D cameraPosition, ref Vector3D cameraUpVector, ref Vector3D cameraForwardVector, out MatrixD result) { Vector3D crossed; Vector3D final; Vector3D difference = objectPosition - cameraPosition; double lengthSq = difference.LengthSquared(); if (MathUtilD.IsZero(lengthSq)) difference = -cameraForwardVector; else difference *= (double)(1.0 / System.Math.Sqrt(lengthSq)); Vector3D.Cross(ref cameraUpVector, ref difference, out crossed); crossed.Normalize(); Vector3D.Cross(ref difference, ref crossed, out final); result.M11 = crossed.X; result.M12 = crossed.Y; result.M13 = crossed.Z; result.M14 = 0.0d; result.M21 = final.X; result.M22 = final.Y; result.M23 = final.Z; result.M24 = 0.0d; result.M31 = difference.X; result.M32 = difference.Y; result.M33 = difference.Z; result.M34 = 0.0d; result.M41 = objectPosition.X; result.M42 = objectPosition.Y; result.M43 = objectPosition.Z; result.M44 = 1.0d; }
/// <summary> /// Creates a right-handed, look-at MatrixD. /// </summary> /// <param name="eye">The position of the viewer's eye.</param> /// <param name="target">The camera look-at target.</param> /// <param name="up">The camera's up vector.</param> /// <param name="result">When the method completes, contains the created look-at MatrixD.</param> public static void LookAtRH(ref Vector3D eye, ref Vector3D target, ref Vector3D up, out MatrixD result) { Vector3D xaxis, yaxis, zaxis; Vector3D.Subtract(ref eye, ref target, out zaxis); zaxis.Normalize(); Vector3D.Cross(ref up, ref zaxis, out xaxis); xaxis.Normalize(); Vector3D.Cross(ref zaxis, ref xaxis, out yaxis); result = MatrixD.Identity; result.M11 = xaxis.X; result.M21 = xaxis.Y; result.M31 = xaxis.Z; result.M12 = yaxis.X; result.M22 = yaxis.Y; result.M32 = yaxis.Z; result.M13 = zaxis.X; result.M23 = zaxis.Y; result.M33 = zaxis.Z; Vector3D.Dot(ref xaxis, ref eye, out result.M41); Vector3D.Dot(ref yaxis, ref eye, out result.M42); Vector3D.Dot(ref zaxis, ref eye, out result.M43); result.M41 = -result.M41; result.M42 = -result.M42; result.M43 = -result.M43; }
/// <summary> /// Creates a right-handed, look-at MatrixD. /// </summary> /// <param name="eye">The position of the viewer's eye.</param> /// <param name="target">The camera look-at target.</param> /// <param name="up">The camera's up vector.</param> /// <returns>The created look-at MatrixD.</returns> public static MatrixD LookAtRH(Vector3D eye, Vector3D target, Vector3D up) { MatrixD result; LookAtRH(ref eye, ref target, ref up, out result); return result; }
public static Vector3D Transform3x3(Vector3D vector, MatrixD transform) { Vector3D result; Transform3x3(ref vector, ref transform, out result); return result; }