10
\$\begingroup\$

I have an angle where I need to convert a 'normal' angle to an isometric angle (116 degrees), and I came up with this function. It works, but I was wondering if the math could be optimized/simplified, or if this is the way to go. It's for a mobile game.

public static inline var ISO:Float = 0.45378560551; // (116-90) / 180 * PI=;
function convert(angle:Float):Float
{ 
 angle -= Math.PI; // corrected angle 
 var randomChoosenDistance = 2.0; // could be anything, I'm only interested in final angle.
 // calculate new line, using isometic angle.
 var x1 = Math.cos(angle - ISO);
 var x2 = Math.cos(angle - ISO) * randomChoosenDistance;
 var y1 = Math.sin(angle);
 var y2 = Math.sin(angle) * randomChoosenDistance;
 var dx = x1 - x2;
 var dy = y1 - y2;
 angle = Math.atan2(dy, dx);
 return angle;
}

Can I get the new angle, without calculating the angle between the temporary points I'm creating at the moment?

200_success
146k22 gold badges190 silver badges478 bronze badges
asked Jan 14, 2014 at 23:08
\$\endgroup\$

2 Answers 2

9
\$\begingroup\$

@neo pointed out that dx can be calculated as (1 - r) * Math.cos(a - b). Similarly, dy = (1 - r) * Math.sin(a). However, when you take dy / dx, which is what Math.atan2(dy, dx) implicitly does with its arguments, the (1 - r) factor cancels out. You can also see, using a geometric argument, that (x2, y2) is pointless (pardon the pun).

Pointlessness of (x2, y2)

Therefore, Math.atan2(y1, x1) would work just the same as Math.atan2(dy, dx).


So far, your function can be simplified to the following. Since you repurposed angle twice, I need to disambiguate them as alpha, beta, and theta for this discussion.

public static inline var ISO:Float = 0.45378560551; // (116-90) / 180 * PI=;
function convert(alpha:Float):Float
{ 
 var beta = alpha - Math.PI; // corrected angle 
 // calculate new line, using isometic angle.
 var x1 = Math.cos(beta - ISO);
 var y1 = Math.sin(beta);
 var theta = Math.atan2(y1, x1);
 return theta;
}

But wait, there's more! There's a mysterious correction from alpha to beta, and the cosine expression is complicated.

Let's start with Math.sin(beta). That's Math.sin(-alpha), or -Math.sin(alpha).

It would be nice to say Math.atan2(Math.sin(alpha), something) instead of Math.atan2(-Math.sin(alpha), something). Let's move the negation into the denominator then, for var theta = Math.atan2(Math.sin(alpha), -x1).

Can we simplify -x1?

-x1 = -Math.cos(beta - ISO)
 = Math.cos(beta - ISO + 180°)
 = Math.cos(alpha - 180° - ISO + 180°)
 = Math.cos(alpha - ISO)

So, your function simplifies to:

public static inline var ISO:Float = 0.45378560551; // = (116-90) / 180 * PI
function convert(angle:Float):Float
{ 
 return Math.atan2(Math.sin(angle), Math.cos(angle - ISO));
}

Not only is the code more efficient, it's also less mysterious: the transformation is taking the x-coordinate of each point as if it were rotated 26° clockwise!


I have to question the motivation behind this function, though. This isn't an angle-preserving transformation, so why are you operating on an angle? Normally, you transform points' coordinates using matrix multiplication.

answered Jan 19, 2014 at 20:21
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for taking time to this in-depth answer! It's very clear. About how I'm using this function: I have spritesheets from an old game that are drawn in isometric perspective, but my game itself runs in normal perspective (it only looks isometric). I'm using this function to get the right index on the spritesheet. So yes; I have to admit this function is very project specific. \$\endgroup\$ Commented Jan 20, 2014 at 14:19
5
\$\begingroup\$

It seems to me that this is a math related question rather than code review. Let's simplify the code first,

var dx = Math.cos(a - b) - Math.cos(a - b) * r;

The above can be simplified to

var dx = (1 - r) * Math.cos(a - b);

One less Math.cos() and one less multiplication is being called, which could be CPU consuming.

Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
answered Jan 15, 2014 at 3:45
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.