@@ -108,4 +108,61 @@ public static Vector rotateVector(Vector v, float yawDegrees, float pitchDegrees
108108
109109 return new Vector (x , y , z );
110110 }
111+
112+ /**
113+ * 判断一个向量是否已单位化
114+ *
115+ * @param vector 向量
116+ * @return 是否单位化
117+ */
118+ public static boolean isNormalized (Vector vector ) {
119+ return Math .abs (vector .lengthSquared () - 1 ) < Vector .getEpsilon ();
120+ }
121+
122+ /**
123+ * 空间向量绕任一向量旋转
124+ *
125+ * @param vector 待旋转向量
126+ * @param axis 旋转轴向量
127+ * @param angle 旋转角度
128+ * @return {@link Vector}
129+ */
130+ public static Vector rotateAroundAxis (Vector vector , Vector axis , double angle ) {
131+ return rotateAroundNonUnitAxis (vector , isNormalized (axis ) ? axis : axis .clone ().normalize (), angle );
132+ }
133+
134+ /**
135+ * 空间向量绕任一向量旋转
136+ * <p>注: 这里的旋转轴必须为已单位化才可使用!</p>
137+ * <p>
138+ * 罗德里格旋转公式: https://zh.wikipedia.org/wiki/%E7%BD%97%E5%BE%B7%E9%87%8C%E6%A0%BC%E6%97%8B%E8%BD%AC%E5%85%AC%E5%BC%8F
139+ * <p>
140+ * 正常人能看懂的: https://www.cnblogs.com/wubugui/p/3734627.html
141+ *
142+ * @param vector 要旋转的向量
143+ * @param axis 旋转轴向量
144+ * @param angle 旋转角度
145+ * @return {@link Vector}
146+ */
147+ public static Vector rotateAroundNonUnitAxis (Vector vector , Vector axis , double angle ) {
148+ double x = vector .getX (), y = vector .getY (), z = vector .getZ ();
149+ double x2 = axis .getX (), y2 = axis .getY (), z2 = axis .getZ ();
150+
151+ double cosTheta = Math .cos (angle );
152+ double sinTheta = Math .sin (angle );
153+ double dotProduct = vector .dot (axis );
154+
155+ double xPrime = x2 * dotProduct * (1d - cosTheta )
156+ + x * cosTheta
157+ + (-z2 * y + y2 * z ) * sinTheta ;
158+ double yPrime = y2 * dotProduct * (1d - cosTheta )
159+ + y * cosTheta
160+ + (z2 * x - x2 * z ) * sinTheta ;
161+ double zPrime = z2 * dotProduct * (1d - cosTheta )
162+ + z * cosTheta
163+ + (-y2 * x + x2 * y ) * sinTheta ;
164+
165+ return vector .setX (xPrime ).setY (yPrime ).setZ (zPrime );
166+ }
167+
111168}
0 commit comments