| 1150 | " :return: angle in radians or fallback when given\n" |
| 1151 | " :rtype: float | Any\n"); |
| 1152 | static PyObject *Vector_angle(VectorObject *self, PyObject *args) |
| 1153 | { |
| 1154 | const int vec_num = std::min(self->vec_num, 3); /* 4D angle makes no sense */ |
| 1155 | float tvec[MAX_DIMENSIONS]; |
| 1156 | PyObject *value; |
| 1157 | double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f; |
| 1158 | int x; |
| 1159 | PyObject *fallback = nullptr; |
| 1160 | |
| 1161 | if (!PyArg_ParseTuple(args, "O|O:angle", &value, &fallback)) { |
| 1162 | return nullptr; |
| 1163 | } |
| 1164 | |
| 1165 | if (BaseMath_ReadCallback(self) == -1) { |
| 1166 | return nullptr; |
| 1167 | } |
| 1168 | |
| 1169 | /* don't use clamped size, rule of thumb is vector sizes must match, |
| 1170 | * even though n this case 'w' is ignored */ |
| 1171 | if (mathutils_array_parse( |
| 1172 | tvec, self->vec_num, self->vec_num, value, "Vector.angle(other), invalid 'other' arg") == |
| 1173 | -1) |
| 1174 | { |
| 1175 | return nullptr; |
| 1176 | } |
| 1177 | |
| 1178 | if (self->vec_num > 4) { |
| 1179 | PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D"); |
| 1180 | return nullptr; |
| 1181 | } |
| 1182 | |
| 1183 | for (x = 0; x < vec_num; x++) { |
| 1184 | dot_self += double(self->vec[x]) * double(self->vec[x]); |
| 1185 | dot_other += double(tvec[x]) * double(tvec[x]); |
| 1186 | dot += double(self->vec[x]) * double(tvec[x]); |
| 1187 | } |
| 1188 | |
| 1189 | if (!dot_self || !dot_other) { |
| 1190 | /* avoid exception */ |
| 1191 | if (fallback) { |
| 1192 | Py_INCREF(fallback); |
| 1193 | return fallback; |
| 1194 | } |
| 1195 | |
| 1196 | PyErr_SetString(PyExc_ValueError, |
| 1197 | "Vector.angle(other): " |
| 1198 | "zero length vectors have no valid angle"); |
| 1199 | return nullptr; |
| 1200 | } |
| 1201 | |
| 1202 | return PyFloat_FromDouble(safe_acosf(dot / (sqrt(dot_self) * sqrt(dot_other)))); |
| 1203 | } |
| 1204 | |
| 1205 | /** \} */ |
| 1206 |
nothing calls this directly
no test coverage detected