Sign in to follow this  

[Solved] Rotation around localx and a specified point.. What's wrong?

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all! I made a camera class, it has a camera eyepoint in the scene graph, and calling movement methods of this class will move the eyepoint accordingly.. for example calling pan(dx,dy) will call eye.TranslateLocal(dx,dy,0).. etc. The problem is with the orbit method.. I want the camera to rotate around its target while looking at it. horizontal rotation is no problem, it's just rotation around the parent Z axis, like this:
    Public Sub Orbit(ByVal angle As Single)
        mEye.LocalTransform *= Transform.Tranlation(-mLocalTarget) * Transform.RotationZ(-angle) * Transform.Tranlation(mLocalTarget)
    End Sub

where the Transform class is similar to the matrix class of directx. now when I try to rotate vertically, I have to rotate around the target's location and the axis is the eyepoint's local x. first I tried to do this:
    Public Sub Tilt(ByVal angle As Single)
        Dim relation As Vector3 = mLocalTarget - mEye.LocalPosition
        mEye.LocalTransform = Transform.Tranlation(-mLocalTarget) * Transform.Tranlation(relation) * Transform.RotationX(angle) * Transform.Tranlation(-relation) * Transform.Tranlation(mLocalTarget) * mEye.LocalTransform

    End Sub

but this made the eyepoint rotate around a point somewhere between it and the target... I then tried this:
    Public Sub Tilt(ByVal angle As Single)
        Dim relation As Vector3 = mLocalTarget - mEye.LocalPosition
        Dim z As New Vector3(0, 0, 1)

        Dim rNorm As Vector3 = relation
        rNorm.Normalize()

        Dim left As Double = Math.Acos(Vector3.Dot(rNorm, z))

        Dim res As Double = left + angle
        If (res > 0) AndAlso (res < Math.PI) Then
           Dim x As Vector3 = Vector3.Cross(z, relation)
           x.Normalize()
           Dim m As Matrix = Matrix.RotationAxis(x, angle)
           relation = Vector3.TransformNormal(relation, m)
           mEye.LocalRotationMatrix *= m
           mEye.LocalPosition = mLocalTarget - relation
        End If
     End Sub

and this worked quite fine, untill it randomally starts to sway around with not obvious reason.. I spent days trying different ways and nothing worked. it's either a precision problem or something similar.. Please help!! I'm using managed directx9 [Edited by - Elias on May 26, 2007 1:01:01 PM]

Share this post


Link to post
Share on other sites
The problem was in the precision of the calculations. Rotation around the localX vector should never change it, but actually it does change it a VERY little bit, so using the new vector next time will cause more error.. and those errors accomulate making the camera sway around.

I had to use a way that doesn't make direct use of that vectore, so I used triangles!

The camera moves on a sphere which center is the target, so the start point, the end point and the center make a triangle with two equal segments. The length of each of them is the radius, and the angle between them is the angle of rotation.

I just had to find the angle at the base, and use it to calculate the translation that needs to be done, then rotate to acheive the required rotation.

Here's the code for this:
      Public Sub Tilt(ByVal angle As Single)
'Calculate the radius of the sphere
Dim radiusVec As Vector3 = mLocalTarget - mEye.LocalPosition
Dim a As Double = CDbl(radiusVec.Length)

'Calculate the length of the base where the equal segments are a and the base is c
Dim c As Double = a * Math.Sqrt(2.0# - 2.0# * Math.Cos(CDbl(angle)))

'Calculate the base angle
Dim baseAngle As Double = 0.5# * (Math.PI - Math.Abs(CDbl(angle)))

'Calculate the required translation
Dim dz As Single = CSng(c * Math.Cos(baseAngle))
Dim dy As Single = CSng(c * Math.Sin(baseAngle) * Math.Sign(angle))
mEye.TranslateLocal(0, dy, dz)

'Finally, Rotate the camera (for some reason, this method doesn't cause error, or I would have had to do it manually as well)
mEye.RotateLocalX(angle)
End Sub

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this