本文整理汇总了C++中ofVec3f::lengthSquared方法的典型用法代码示例。如果您正苦于以下问题:C++ ofVec3f::lengthSquared方法的具体用法?C++ ofVec3f::lengthSquared怎么用?C++ ofVec3f::lengthSquared使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ofVec3f
的用法示例。
在下文中一共展示了ofVec3f::lengthSquared方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: makeRotate
/** Make a rotation Quat which will rotate vec1 to vec2
This routine uses only fast geometric transforms, without costly acos/sin computations.
It's exact, fast, and with less degenerate cases than the acos/sin method.
For an explanation of the math used, you may see for example:
http://logiciels.cnes.fr/MARMOTTES/marmottes-mathematique.pdf
@note This is the rotation with shortest angle, which is the one equivalent to the
acos/sin transform method. Other rotations exists, for example to additionally keep
a local horizontal attitude.
@author Nicolas Brodu
*/
void ofQuaternion::makeRotate( const ofVec3f& from, const ofVec3f& to ) {
// This routine takes any vector as argument but normalized
// vectors are necessary, if only for computing the dot product.
// Too bad the API is that generic, it leads to performance loss.
// Even in the case the 2 vectors are not normalized but same length,
// the sqrt could be shared, but we have no way to know beforehand
// at this point, while the caller may know.
// So, we have to test... in the hope of saving at least a sqrt
ofVec3f sourceVector = from;
ofVec3f targetVector = to;
float fromLen2 = from.lengthSquared();
float fromLen;
// normalize only when necessary, epsilon test
if ((fromLen2 < 1.0 - 1e-7) || (fromLen2 > 1.0 + 1e-7)) {
fromLen = sqrt(fromLen2);
sourceVector /= fromLen;
} else fromLen = 1.0;
float toLen2 = to.lengthSquared();
// normalize only when necessary, epsilon test
if ((toLen2 < 1.0 - 1e-7) || (toLen2 > 1.0 + 1e-7)) {
float toLen;
// re-use fromLen for case of mapping 2 vectors of the same length
if ((toLen2 > fromLen2 - 1e-7) && (toLen2 < fromLen2 + 1e-7)) {
toLen = fromLen;
} else toLen = sqrt(toLen2);
targetVector /= toLen;
}
// Now let's get into the real stuff
// Use "dot product plus one" as test as it can be re-used later on
double dotProdPlus1 = 1.0 + sourceVector.dot(targetVector);
// Check for degenerate case of full u-turn. Use epsilon for detection
if (dotProdPlus1 < 1e-7) {
// Get an orthogonal vector of the given vector
// in a plane with maximum vector coordinates.
// Then use it as quaternion axis with pi angle
// Trick is to realize one value at least is >0.6 for a normalized vector.
if (fabs(sourceVector.x) < 0.6) {
const double norm = sqrt(1.0 - sourceVector.x * sourceVector.x);
_v[0] = 0.0;
_v[1] = sourceVector.z / norm;
_v[2] = -sourceVector.y / norm;
_v[3] = 0.0;
} else if (fabs(sourceVector.y) < 0.6) {
const double norm = sqrt(1.0 - sourceVector.y * sourceVector.y);
_v[0] = -sourceVector.z / norm;
_v[1] = 0.0;
_v[2] = sourceVector.x / norm;
_v[3] = 0.0;
} else {
const double norm = sqrt(1.0 - sourceVector.z * sourceVector.z);
_v[0] = sourceVector.y / norm;
_v[1] = -sourceVector.x / norm;
_v[2] = 0.0;
_v[3] = 0.0;
}
}
else {
// Find the shortest angle quaternion that transforms normalized vectors
// into one other. Formula is still valid when vectors are colinear
const double s = sqrt(0.5 * dotProdPlus1);
const ofVec3f tmp = sourceVector.getCrossed(targetVector) / (2.0 * s);
_v[0] = tmp.x;
_v[1] = tmp.y;
_v[2] = tmp.z;
_v[3] = s;
}
}