# How to prevent fish eye effect when using CCOrbitCamera in Cocos2D?

Note: I'm using CocosSharp, a Xamarin C# version but the question is valid for all Cocos2D versions I presume. I'm also fine with answers in any Cocos2D dialect (there is no tag yet for CocosSharp here).

I'm trying to create a card flip animation using CCOrbitCamera. This works pretty well with the code below - unless the sprite ist not in the center of the screen.

var animateInFirstHalf = new CCOrbitCamera(animDurationSeconds, 1, 0, 0, 90f, 0, 0);


My idea is to flip the card 90 degrees, then exchange the texture, and flip further. At 90 degrees the only thing that's visible is a thin line if the sprite is centered. If it is out of the center, it looks something like this:

The picture is from a blog post where the issue was solved by faking the animation with skew and scale. However I wonder if it is possible to somehow run the animation as if the sprite was centered? Something like virtually translating it to the center.

I don't know how to prevent eye effect, but for the problem you mentioned in question body ( to create a card flip ), you can use x-scaling technique as:

[ ] => [] => | => change texture => | => [] => [ ]

As I used this technique, I promise you that it will be what you want even if cards are out of the screen center.

• This is what I ended up using with a little shear. – Krumelur Feb 16 '15 at 11:37

Like you said, the card is just a thin line when centered on the screen in the x-axis at 90 degrees, at any other position (including the above case) the card will be a thin line when it aligns with the normal from the camera to the card's centre.

Using the dot product between two angles you can figure out the angle between them, so from the cameras position you want the angle between the direction straight forward and the direction to the card.

Here's some pseudocode (I don't use cocos2d so the function names might be different):

toCard = (card.centre - camera.position).normalize
angle = inverseCos( toCard.dot(camera.facingNormal) )


This is the difference in angle from the 90 degree rotation you used before, now you just have to figure out if the card is to the right or the left of the centre of the screen.

if (card.x <= screen.width / 2)
90 - angle   or   Pi/2 - angle
else
90 + angle   or   Pi/2 + angle


One little caveat though, if your card is above or below the centre of the screen the difference in y coordinates will make the angle come out wrong, in that case just use 0 as y coordinate for both the card's centre and the cameras position.

Now you rotate to this new calculated angle, once the card reaches that point, swap the texture, then rotate from that point to fully flipped over. Hope it was clear enough and useful to you