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.
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.