# Arcball problem

This topic is 2595 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

I'm trying to add an "arc ball" but I have a strange behaviour.
I surely do something wrong, but what :-P So, if someone has an idea of the problem ?

How to reproduce it :
1 - With my arcball, I do an horizontal rotation of 180 degree (all is fine)
2 - I try to do a vertical rotation and the scene rotate in the INVERSE direction

Here is what I do :

void TrackballOperator::OnMouseMove(MouseEventArgs* e){	if (e->LeftButtonStatus == Down)	{		Drag(e->x, e->y);		// Update the camera		VNCamera* camera = _surface->GetScene()->GetActiveCamera();		Vector3 at = camera->GetEyeAt();		// eye				Vector3 eye = _startVector - at;		GlobalRotation.Rotate(&eye);		camera->SetEye(eye + at);		// eye up		Vector3 eyeUp = _startVectorUp;		GlobalRotation.Rotate(&eyeUp);		camera->SetEyeUp(eyeUp);	}}void TrackballOperator::OnMouseButtonDown(MouseButtonEventArgs* e){	if (e->Button == Left)	{		SetBounds(_surface->GetWidth(), _surface->GetHeight());		//---- Reset some datas...		VNCamera* camera = _surface->GetScene()->GetActiveCamera();		_startVector = camera->GetEye();		_startVectorUp = camera->GetEyeUp();		startMouse.x = e->x;		startMouse.y = e->y;		GlobalRotation.AsIdentity();	}}void TrackballOperator::MapToSphere(const Vector2* NewPt, Vector3* NewVec) const{    Vector2 TempPt;    float length;    // Copy paramter into temp point    TempPt = *NewPt;    // Adjust point coords and scale down to range of [-1 ... 1]    TempPt.x  =        (TempPt.x * this->AdjustWidth)  - 1.0f;    TempPt.y  = 1.0f - (TempPt.y * this->AdjustHeight);    // Compute the square of the length of the vector to the point from the center    length      = (TempPt.x * TempPt.x) + (TempPt.y * TempPt.y);    // If the point is mapped outside of the sphere... (length > radius squared)    if (length > 1.0f)    {        float norm;        // Compute a normalizing factor (radius / sqrt(length))        norm    = 1.0f / sqrtf(length);        // Return the "normalized" vector, a point on the sphere        NewVec->x = TempPt.x * norm;        NewVec->y = TempPt.y * norm;        NewVec->z = 0.0f;    }    else                                          //Else it's on the inside    {        //Return a vector to a point mapped inside the sphere sqrt(radius squared - length)        NewVec->x = TempPt.x;        NewVec->y = TempPt.y;        NewVec->z = sqrtf(1.0f - length);    }}void TrackballOperator::Drag(float newX, float newY){    endMouse.x = newX;    endMouse.y = newY;    // Map the point to the sphere    Vector3 startPoint;    Vector3 endPoint;    MapToSphere(&startMouse, &startPoint);    MapToSphere(&endMouse, &endPoint);    // Return the quaternion equivalent to the rotation    // Compute the vector perpendicular to the begin and end vectors    Vector3 Perp = Cross(endPoint, startPoint);    startMouse = endMouse;    // Compute the length of the perpendicular vector    Quaternion NewRot;	if (Perp.Length() < EPSILON)        return;    // We're ok, so return the perpendicular vector as the transform after all    NewRot.x = Perp.x;    NewRot.y = Perp.y;    NewRot.z = Perp.z;    // In the quaternion values, w is cosine (theta / 2), where theta is rotation angle    NewRot.w = Dot(startPoint, endPoint);    GlobalRotation = GlobalRotation * NewRot;}

About the quaternion class :

	// Conjugate it	void Conjugate()	{		x = -x;		y = -y;		z = -z;	}	// Calculates the effect of this rotation on a point    // the new point is given by = q * P1 * q'    void Rotate(Vector3* point)	{		//---- Compute the conjugate		Quaternion conj = *this;		conj.Conjugate();		//---- q * P * q'		Quaternion qNode(point->x, point->y, point->z, 0.f);		qNode = *this * qNode * conj;		//---- Set the result		point->x = qNode.x;		point->y = qNode.y;		point->z = qNode.z;	}

##### Share on other sites
I think I have found the problem.

I need to set-up my initial quaternion with the camera axis.

So, do you know how to convert 3 Axis (AxisX, AxisY, AxisZ) into a quaternion ?

Thanks for your help