# Trackball rotate的OSG实现（一）（不是manipulator那种~是动物体那种！）

z(x,y)=r2((xOx)2+(yOy)2)+Oz,r2/2(xOx)2+(yOy)2+Ozif (xOx)2+(yOy)2r22

V1=(x1Ox,y1Oy,z1Oz)

osg::Vec3 TrackballRotate::projectToSphere(osg::Vec3 xy, osg::Vec3 center, float radius){
osg::Vec3 cameraPoint = screen2Camera(xy);
osg::Vec3 cameraCenter = world2Camera(center);
float x2 = (cameraPoint.x() - cameraCenter.x())*(cameraPoint.x() - cameraCenter.x());
float y2 = (cameraPoint.y() - cameraCenter.y())*(cameraPoint.y() - cameraCenter.y());
float z;
if (x2 + y2 <= restrain)//在球内部
{
z = sqrtf(radius*radius - (x2 + y2)) + cameraCenter.z();
}
else
{
z = restrain / sqrtf(x2 + y2) + cameraCenter.z();
}
osg::Vec3 v;
v = { cameraPoint.x(), cameraPoint.y() , z };//相机空间中映射到的点
v = camera2World(v);
osg::Vec3 vr = v - center;
float length = vr.length();
vr = vr / length;
return v;
}


void TrackballRotate::GetRotateParameter(osg::Vec3 oldP, osg::Vec3 newP, osg::Vec3 center, float radius)
{

osg::Vec3 delta = newP - oldP;
if (delta.length2() <= 4)
{
return;
}
//先将这两个点投影到球面，获得z坐标。
osg::Vec3 p1 = projectToSphere(oldP, center, radius);
osg::Vec3 p2 = projectToSphere(newP, center, radius);
osg::Vec3 k = p1^p2;//叉乘为旋转轴
k = k / k.length();
float angle = acos(p1*p2 / (p1.length()*p2.length()));//点乘求得夹角
//float angle = acos(p1*p2);//点乘求得夹角
float cosangle = cos(angle / 2);
float sinangle = sin(angle / 2);//  k *= sinangle;
//osg::Vec3 rotate_axis = k;
rotateParameter = { angle, k };}