Swift: Orient Y-Axis Toward Another Point in 3-D Space

swift: orient y-axis toward another point in 3-d space

Got it! Incredibly simple when you add a container node. The following seems to work for any positions in any quadrants.

// pointAt_c is a container node located at, and child of, the originNode
// pointAtNode is its child, position coincident with pointAt_c (and originNode)

// get deltas (positions of target relative to origin)
let dx = targetNode.position.x - originNode.position.x
let dy = targetNode.position.y - originNode.position.y
let dz = targetNode.position.z - originNode.position.z

// rotate container node about y-axis (pointAtNode rotated with it)
let y_angle = atan2(dx, dz)
pointAt_c.rotation = SCNVector4(0.0, 1.0, 0.0, y_angle)

// now rotate the pointAtNode about its z-axis
let dz_dx = sqrt((dz * dz) + (dx * dx))

// (due to rotation the adjacent side of this angle is now a hypotenuse)
let x_angle = atan2(dz_dx, dy)
pointAtNode.rotation = SCNVector4(1.0, 0.0, 0.0, x_angle)

I needed this to replace lookAt constraints which cannot, easily anyway, be archived with a node tree. I'm pointing the y-axis because that's how SCN cylinders and capsules are directed.

If anyone knows how to obviate the container node please do tell. Everytime I try to apply sequential rotations to a single node, the last overwrites the previous one. I haven't the knowledge to formulate a rotation expression to do it in one shot.

How to minimize floating point inaccuracy in rotating a point in 3D space about an arbitrary axis?

Due to my lengthy web searches, I finally arrived to the conclusion that I should use Quaternions. Using the current method, I found out that excessive operations on floating point variables will increase round errors. Using Quaternions was simpler and cleaner.

Here's the code if anyone is interested:

private static Vector3 RotateArbitrary(Vector3 Point, Vector3 AxisPoint, Vector3 AxisDirection, float Radians)
{
return Vector3.Add(Vector3.Transform(Vector3.Subtract(Point, AxisPoint), Quaternion.FromAxisAngle(AxisDirection, Radians)), AxisPoint);
}

Take note that the the Point was translated first such that the AxisPoint is at the origin, with that, rotations can be done. The result is then translated to its original position.



Related Topics



Leave a reply



Submit