1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
void Rotation2(int x1, int y1, int x2, int y2, float fTrackBallRadius)
{
// inspiré de http://www2.lifl.fr/~triquet/tools/trackball.cpp et d'un exemple de DirectX
float xpos1 = (((2.0f * (float)x1) / this.Width) - 1);
float ypos1 = (((2.0f * (float)y1) / this.Height) - 1);
float sz1;
float xpos2 = (((2.0f * (float)x2) / this.Width) - 1);
float ypos2 = (((2.0f * (float)y2) / this.Height) - 1);
float sz2;
float t;
if ((xpos2 == xpos1) && (ypos2 == ypos1))
return;
float d2 = (float)Math.Sqrt(xpos1 * xpos1 + ypos1 * ypos1);
if (d2 < fTrackBallRadius * 0.70710678118654752440) // Inside sphere
sz1 = (float)Math.Sqrt(fTrackBallRadius * fTrackBallRadius - d2 * d2);
else
{
// On hyperbola
t = fTrackBallRadius / 1.41421356237309504880f;
sz1 = (t * t) / d2;
}
d2 = (float)Math.Sqrt(xpos2 * xpos2 + ypos2 * ypos2);
if (d2 < fTrackBallRadius * 0.70710678118654752440) // Inside sphere
sz2 = (float)Math.Sqrt(fTrackBallRadius * fTrackBallRadius - d2 * d2);
else // On hyperbola
{
// On hyperbola
t = fTrackBallRadius / 1.41421356237309504880f;
sz2 = (t * t) / d2;
}
// Get two points on trackball's sphere
Vector3 p1 = new Vector3(xpos1, ypos1, sz1);
Vector3 p2 = new Vector3(xpos2, ypos2, sz2);
// Get axis of rotation, which is cross product of p1 and p2
Vector3 axis = Vector3.Cross(p1, p2);
axis.Normalize();
// Calculate angle for the rotation about that axis
t = Vector3.Length(Vector3.Subtract(p2, p1)) / (2.0f * fTrackBallRadius);
if (t > +1.0f) t = +1.0f;
if (t < -1.0f) t = -1.0f;
float fAngle = (float)(2.0f * Math.Asin(t));
// On calcule les angles de rotation, voire http://jeux.developpez.com/faq/matquat/?page=transformations#Q37
Vector3 vrot = c3d.RotationObjets;
vrot.X += fAngle * axis.X;
vrot.Y += fAngle * axis.Y;
vrot.Z += fAngle * axis.Z;
} |
Partager