Skip to content

Commit b7b88ce

Browse files
Create a Quaternion representing the rotation from one vector to another (#54)
1 parent bda8752 commit b7b88ce

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/commonMain/kotlin/dev/romainguy/kotlin/math/Quaternion.kt

+32
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,38 @@ data class Quaternion(
130130
)
131131
}
132132
}
133+
134+
/**
135+
* Create a Quaternion representing the shortest rotation from one vector to another.
136+
*
137+
* Both vectors are assumed to be unit length.
138+
*
139+
* @param from the initial vector
140+
* @param to the destination vector
141+
*/
142+
fun fromRotation(from: Float3, to: Float3): Quaternion {
143+
// This implementation might still be improvable: https://stackoverflow.com/a/11741520
144+
val dotProduct = dot(from, to)
145+
// Handle the case of parallel vectors (both in the same direction or pointing in
146+
// opposite directions)
147+
return when {
148+
dotProduct < -0.9999999f -> {
149+
val crossProd = cross(Float3(x = 1.0f), from)
150+
fromAxisAngle(
151+
axis = normalize(
152+
when {
153+
length(crossProd) < 0.0000001f -> cross(Float3(y = 1.0f), from)
154+
else -> crossProd
155+
}
156+
),
157+
angle = 180.0f
158+
)
159+
}
160+
161+
dotProduct > 0.9999999f -> Quaternion()
162+
else -> normalize(Quaternion(cross(from, to), w = 1.0f + dotProduct))
163+
}
164+
}
133165
}
134166

135167
inline var xyz: Float3

0 commit comments

Comments
 (0)