how to rotate a vector around an arbitrary axis?

Viewed 341

I have an axis, as defined by 2 vectors, for example one that points upwards at x = 10:

const axisStart = new Vector3(10, 0, 0)
const axisEnd = new Vector3(10, 0, 1)

I'm getting the normalized axis direction like so:

const axisDirection = new Vector3().subVectors(axisEnd, axisStart).normalize()

How can I rotate a vector (e.g. Vector3(50, 0, 0)) around my original axis?

I've tried using Vector3.applyAxisAngle(axisDirection , radians), but because the axis has been normalized, the rotation happens around the world center (0, 0) and not around the axis' original position.

1 Answers

I've solved this by finding the exact point on the axis around which the point rotates, using this answer and translating the pseudocode from it into typescript:

getPivotPoint(pointToRotate: Vector3, axisStart: Vector3, axisEnd: Vector3) {
    const d = new Vector3().subVectors(axisEnd, axisStart).normalize()
    const v = new Vector3().subVectors(pointToRotate, axisStart)
    const t = v.dot(d)
    const pivotPoint = axisStart.add(d.multiplyScalar(t))
    return pivotPoint
  }

Then, as @Ouroborus pointed out, I can then translate the point, apply the rotation, and translate it back:

rotatePointAroundAxis(pointToRotate: Vector3, axisStart: Vector3, axisEnd, radians: number) {
    const axisDirection = new Vector3().subVectors(axisEnd, axisStart).normalize()
    const pivotPoint = getPivotPoint(pointToRotate, axisStart, axisEnd)
    const translationToWorldCenter = new Vector3().subVectors(pointToRotate, pivotPoint)
    const translatedRotated = translationToWorldCenter.clone().applyAxisAngle(axisDirection, radians)
    const destination = pointToRotate.clone().add(translatedRotated).sub(translationToWorldCenter)
    return destination
  }

The above code is working nicely, leaving it here for my future self and for other who might find this useful.

Related