Sevdat Posted July 25 Posted July 25 (edited) Good evening, I wrote this code in unity to rotate a vec3 point around another vec3 point (with a bit of help from Deepseek): public static class QuaternionClass { public static Vector4 quatMul(Vector4 q1, Vector4 q2) { float w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z; float x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y; float y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x; float z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w; return new Vector4(x, y, z, w); } public static Vector4 angledAxis(float angle,Vector3 rotationAxis){ Vector3 perpendicular = VectorManipulator.normalizeVector3(rotationAxis); float halfAngle = angle * 0.5f * (Mathf.PI/180.0f); float sinHalfAngle = Mathf.Sin(halfAngle); float w = Mathf.Cos(halfAngle); float x = perpendicular.x * sinHalfAngle; float y = perpendicular.y * sinHalfAngle; float z = perpendicular.z * sinHalfAngle; return new Vector4(x,y,z,w); } public static Vector3 rotate( Vector3 origin, Vector3 point,Vector4 angledAxis ){ Vector3 rotatedVec = origin; if (point != origin){ Vector3 pointDirection = VectorManipulator.vectorDirections(origin,point); Vector4 rotatingVector = new Vector4(pointDirection.x, pointDirection.y, pointDirection.z,0); Vector4 inverseQuat = new Vector4(-angledAxis.x,-angledAxis.y,-angledAxis.z,angledAxis.w); Vector4 rotatedQuaternion = quatMul(quatMul(angledAxis,rotatingVector), inverseQuat); rotatedVec = origin + new Vector3( rotatedQuaternion.x, rotatedQuaternion.y, rotatedQuaternion.z ); } return rotatedVec; } } I want to do it using your library, but I can't really seem to understand how to do it: https://developer.unigine.com/en/docs/latest/api/library/math/cs/quat?rlang=cpp&autotranslate=en If I do something like this it only rotates the object around itself: ObjectMeshDynamic clone; public ObjectMeshDynamic createCube(vec3 size,vec3 position,int i){ ObjectMeshDynamic cube = Primitives.CreateBox(size); cube.TriggerInteractionEnabled = true; cube.SetIntersection(true, 0); cube.SetIntersectionMask(1, 0); cube.SetCollision(true,0); cube.SetCollisionMask(1, 0); cube.WorldPosition = position; cube.Name = $"{i}"; BodyRigid bodySphere = new BodyRigid(cube); new ShapeSphere(bodySphere, 2); bodySphere.ShapeBased = false; bodySphere.Mass = 1f; return cube; } private void Init(){ Visualizer.Enabled = true; Unigine.Console.Onscreen = true; Physics.ShowShapes = Physics.SHOW_TYPE.SOLID; Physics.ShowJoints = true; Physics.ShowCollisionSurfaces = true; vec3 pos = new vec3(0,0,5); clone = createCube(new vec3(1,1,1),pos,1); } float count = 0; private void Update(){ clone.SetWorldRotation(new quat(new vec3(0,0,1),count)); count += 0.1f; } How can I rotate a vec3 point around another vec3 point? Edited July 25 by Sevdat
Sevdat Posted July 27 Author Posted July 27 On 7/25/2024 at 1:06 PM, Sevdat said: Good evening, I wrote this code in unity to rotate a vec3 point around another vec3 point (with a bit of help from Deepseek): public static class QuaternionClass { public static Vector4 quatMul(Vector4 q1, Vector4 q2) { float w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z; float x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y; float y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x; float z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w; return new Vector4(x, y, z, w); } public static Vector4 angledAxis(float angle,Vector3 rotationAxis){ Vector3 perpendicular = VectorManipulator.normalizeVector3(rotationAxis); float halfAngle = angle * 0.5f * (Mathf.PI/180.0f); float sinHalfAngle = Mathf.Sin(halfAngle); float w = Mathf.Cos(halfAngle); float x = perpendicular.x * sinHalfAngle; float y = perpendicular.y * sinHalfAngle; float z = perpendicular.z * sinHalfAngle; return new Vector4(x,y,z,w); } public static Vector3 rotate( Vector3 origin, Vector3 point,Vector4 angledAxis ){ Vector3 rotatedVec = origin; if (point != origin){ Vector3 pointDirection = VectorManipulator.vectorDirections(origin,point); Vector4 rotatingVector = new Vector4(pointDirection.x, pointDirection.y, pointDirection.z,0); Vector4 inverseQuat = new Vector4(-angledAxis.x,-angledAxis.y,-angledAxis.z,angledAxis.w); Vector4 rotatedQuaternion = quatMul(quatMul(angledAxis,rotatingVector), inverseQuat); rotatedVec = origin + new Vector3( rotatedQuaternion.x, rotatedQuaternion.y, rotatedQuaternion.z ); } return rotatedVec; } } I want to do it using your library, but I can't really seem to understand how to do it: https://developer.unigine.com/en/docs/latest/api/library/math/cs/quat?rlang=cpp&autotranslate=en If I do something like this it only rotates the object around itself: ObjectMeshDynamic clone; public ObjectMeshDynamic createCube(vec3 size,vec3 position,int i){ ObjectMeshDynamic cube = Primitives.CreateBox(size); cube.TriggerInteractionEnabled = true; cube.SetIntersection(true, 0); cube.SetIntersectionMask(1, 0); cube.SetCollision(true,0); cube.SetCollisionMask(1, 0); cube.WorldPosition = position; cube.Name = $"{i}"; BodyRigid bodySphere = new BodyRigid(cube); new ShapeSphere(bodySphere, 2); bodySphere.ShapeBased = false; bodySphere.Mass = 1f; return cube; } private void Init(){ Visualizer.Enabled = true; Unigine.Console.Onscreen = true; Physics.ShowShapes = Physics.SHOW_TYPE.SOLID; Physics.ShowJoints = true; Physics.ShowCollisionSurfaces = true; vec3 pos = new vec3(0,0,5); clone = createCube(new vec3(1,1,1),pos,1); } float count = 0; private void Update(){ clone.SetWorldRotation(new quat(new vec3(0,0,1),count)); count += 0.1f; } How can I rotate a vec3 point around another vec3 point? Good evening, I converted the code to unigine version: ObjectMeshDynamic clone; ObjectMeshDynamic clone2; float angle = 1; vec4 q; vec3 newVec; vec3 axis = new vec3(0,0,1); public ObjectMeshDynamic createCube(vec3 size,vec3 position,int i){ ObjectMeshDynamic cube = Primitives.CreateBox(size); cube.TriggerInteractionEnabled = true; cube.SetIntersection(true, 0); cube.SetIntersectionMask(1, 0); cube.SetCollision(true,0); cube.SetCollisionMask(1, 0); cube.WorldPosition = position; cube.Name = $"{i}"; BodyRigid bodySphere = new BodyRigid(cube); new ShapeSphere(bodySphere, 2); bodySphere.ShapeBased = false; bodySphere.Mass = 1f; bodySphere.Gravity = false; return cube; } public static vec4 quatMul(vec4 q1, vec4 q2) { float w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z; float x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y; float y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x; float z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w; return new vec4(x, y, z, w); } public static vec4 angledAxis(float angle,vec3 rotationAxis){ vec3 perpendicular = rotationAxis.Normalized; float halfAngle = angle * 0.5f * (MathLib.PI/180.0f); float sinHalfAngle = MathLib.Sin(halfAngle); float w = MathLib.Cos(halfAngle); float x = perpendicular.x * sinHalfAngle; float y = perpendicular.y * sinHalfAngle; float z = perpendicular.z * sinHalfAngle; return new vec4(x,y,z,w); } public static vec3 rotate( vec3 origin, vec3 point, vec4 angledAxis ){ vec3 rotatedVec = origin; if (point != origin){ vec3 pointDirection = point - origin; vec4 rotatingVector = new vec4(pointDirection.x, pointDirection.y, pointDirection.z,0); vec4 inverseQuat = new vec4(-angledAxis.x,-angledAxis.y,-angledAxis.z,angledAxis.w); vec4 mul = quatMul(angledAxis,rotatingVector); Log.Message($"mul:{mul}\n"); vec4 rotatedQuaternion = quatMul(mul, inverseQuat); Log.Message($"rotatedQuaternion:{rotatedQuaternion}\n"); rotatedVec = origin + new vec3( rotatedQuaternion.x, rotatedQuaternion.y, rotatedQuaternion.z ); } return rotatedVec; } private void Init(){ Visualizer.Enabled = true; Unigine.Console.Onscreen = true; Physics.ShowShapes = Physics.SHOW_TYPE.SOLID; Physics.ShowJoints = true; Physics.ShowCollisionSurfaces = true; vec3 pos = new vec3(10,10,10); clone = createCube(new vec3(1,1,1),pos,1); clone2 = createCube(new vec3(1,1,1),pos + new vec3(0,5,10),1); q = angledAxis(angle,axis); newVec = rotate(clone.WorldPosition,clone2.WorldPosition,q); clone2.WorldPosition = newVec; } private void Update(){ clone2.WorldPosition = rotate(clone.WorldPosition,clone2.WorldPosition,q); } but I still can't do it using your library. I tried something like this, but it doesn't work. vec3 pos = new vec3(10,10,2); clone = createCube(new vec3(1,1,1),pos,1); clone2 = createCube(new vec3(1,1,1),pos + new vec3(0,5,0),1); q = new quat(pos + new vec3(0,5,0),count); vec3 o = clone2.WorldPosition; vec3 f = q*o*(-q); Log.Message($"{f}\n");
Sevdat Posted July 29 Author Posted July 29 (edited) On 7/27/2024 at 8:23 AM, Sevdat said: Good evening, I converted the code to unigine version: ObjectMeshDynamic clone; ObjectMeshDynamic clone2; float angle = 1; vec4 q; vec3 newVec; vec3 axis = new vec3(0,0,1); public ObjectMeshDynamic createCube(vec3 size,vec3 position,int i){ ObjectMeshDynamic cube = Primitives.CreateBox(size); cube.TriggerInteractionEnabled = true; cube.SetIntersection(true, 0); cube.SetIntersectionMask(1, 0); cube.SetCollision(true,0); cube.SetCollisionMask(1, 0); cube.WorldPosition = position; cube.Name = $"{i}"; BodyRigid bodySphere = new BodyRigid(cube); new ShapeSphere(bodySphere, 2); bodySphere.ShapeBased = false; bodySphere.Mass = 1f; bodySphere.Gravity = false; return cube; } public static vec4 quatMul(vec4 q1, vec4 q2) { float w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z; float x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y; float y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x; float z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w; return new vec4(x, y, z, w); } public static vec4 angledAxis(float angle,vec3 rotationAxis){ vec3 perpendicular = rotationAxis.Normalized; float halfAngle = angle * 0.5f * (MathLib.PI/180.0f); float sinHalfAngle = MathLib.Sin(halfAngle); float w = MathLib.Cos(halfAngle); float x = perpendicular.x * sinHalfAngle; float y = perpendicular.y * sinHalfAngle; float z = perpendicular.z * sinHalfAngle; return new vec4(x,y,z,w); } public static vec3 rotate( vec3 origin, vec3 point, vec4 angledAxis ){ vec3 rotatedVec = origin; if (point != origin){ vec3 pointDirection = point - origin; vec4 rotatingVector = new vec4(pointDirection.x, pointDirection.y, pointDirection.z,0); vec4 inverseQuat = new vec4(-angledAxis.x,-angledAxis.y,-angledAxis.z,angledAxis.w); vec4 mul = quatMul(angledAxis,rotatingVector); Log.Message($"mul:{mul}\n"); vec4 rotatedQuaternion = quatMul(mul, inverseQuat); Log.Message($"rotatedQuaternion:{rotatedQuaternion}\n"); rotatedVec = origin + new vec3( rotatedQuaternion.x, rotatedQuaternion.y, rotatedQuaternion.z ); } return rotatedVec; } private void Init(){ Visualizer.Enabled = true; Unigine.Console.Onscreen = true; Physics.ShowShapes = Physics.SHOW_TYPE.SOLID; Physics.ShowJoints = true; Physics.ShowCollisionSurfaces = true; vec3 pos = new vec3(10,10,10); clone = createCube(new vec3(1,1,1),pos,1); clone2 = createCube(new vec3(1,1,1),pos + new vec3(0,5,10),1); q = angledAxis(angle,axis); newVec = rotate(clone.WorldPosition,clone2.WorldPosition,q); clone2.WorldPosition = newVec; } private void Update(){ clone2.WorldPosition = rotate(clone.WorldPosition,clone2.WorldPosition,q); } but I still can't do it using your library. I tried something like this, but it doesn't work. vec3 pos = new vec3(10,10,2); clone = createCube(new vec3(1,1,1),pos,1); clone2 = createCube(new vec3(1,1,1),pos + new vec3(0,5,0),1); q = new quat(pos + new vec3(0,5,0),count); vec3 o = clone2.WorldPosition; vec3 f = q*o*(-q); Log.Message($"{f}\n"); Good morning, I wrote it using your library, but noticed that rotating by 1 degrees works like rotating 0.5 degrees. rotateAroundPivot.mp4 Rotating 360 degrees is a bit off too. Is everything working as intended? float angle = 1f; vec3 rotationAxis = new vec3(0, 0, 1); ObjectMeshDynamic origin; ObjectMeshDynamic point; float time = 0; float count; public ObjectMeshDynamic createCube(vec3 size,vec3 position,int i){ ObjectMeshDynamic cube = Primitives.CreateBox(size); cube.TriggerInteractionEnabled = true; cube.SetIntersection(true, 0); cube.SetIntersectionMask(1, 0); cube.SetCollision(true,0); cube.SetCollisionMask(1, 0); cube.WorldPosition = position; cube.Name = $"{i}"; BodyRigid bodySphere = new BodyRigid(cube); new ShapeSphere(bodySphere, 2); bodySphere.ShapeBased = false; bodySphere.Mass = 1f; bodySphere.Gravity = false; return cube; } public quat angledAxis(float angle, vec3 rotationAxis){ return new quat(rotationAxis, angle); } public vec3 rotate(vec3 origin, vec3 point, quat angledAxis){ quat q = angledAxis; vec3 v = point - origin; vec3 rotatedOffset = q * v * new quat(new float[] { -q.x, -q.y, -q.z, q.w }); return origin + rotatedOffset; } private void Init(){ Visualizer.Enabled = true; Unigine.Console.Onscreen = true; Physics.ShowShapes = Physics.SHOW_TYPE.SOLID; Physics.ShowJoints = true; Physics.ShowCollisionSurfaces = true; vec3 pivotPosition = new vec3(10, 10, 2); vec3 rotatingPosition = pivotPosition + new vec3(0, 5, 0); origin = createCube(new vec3(1, 1, 1), pivotPosition, 1); point = createCube(new vec3(1, 1, 1), rotatingPosition, 1); } private void Update(){ if (time>0.05){ point.WorldPosition = rotate( origin.WorldPosition, point.WorldPosition, angledAxis(angle,rotationAxis) ); time = 0; count++; if (count>360) count = 0; Log.Message($"{count}\n"); } else time += Game.IFps; } When rotating a mesh do I need to multiply each vertex with a quaternion or is there a more efficient way of rotating them? Edited July 29 by Sevdat 1
Sevdat Posted July 29 Author Posted July 29 (edited) Good evening, As user karpych11 stated: The code above had the mistake in: vec3 rotatedOffset = q * v * new quat(new float[] { -q.x, -q.y, -q.z, q.w }); v is a vector not a quat. It should have been transformed into a quat: quat pureImaginaryQuaternion = new quat(); pureImaginaryQuaternion.x = v.x; pureImaginaryQuaternion.y = v.y; pureImaginaryQuaternion.z = v.z; pureImaginaryQuaternion.w = 0.0f; then it would have been correct. In order to use it the vector way: public quat angledAxis(float angle, vec3 rotationAxis){ return new quat(rotationAxis, angle); } public vec3 rotate(vec3 origin, vec3 point, quat angledAxis){ quat q = angledAxis; vec3 v = point - origin; vec3 rotatedOffset = q * v; return origin + rotatedOffset; } in order to access the math library directly: vec3 rotatedOffset = MathLib.Mul(angledAxis, v); Edited July 29 by Sevdat
Recommended Posts