Fix imprecise rotations bug.

The bug this fixes is documented here: http://youtrack.sk89q.com/issue/WORLDEDIT-3220
This commit is contained in:
Dumbo52 2015-02-21 17:52:22 -05:00
parent 2009344058
commit 8b2bf84b5e
2 changed files with 65 additions and 9 deletions

View File

@ -47,4 +47,62 @@ public final class MathUtils {
return (int) (a - n * Math.floor(Math.floor(a) / n));
}
/**
* Returns the cosine of an angle given in degrees. This is better than
* just {@code Math.cos(Math.toRadians(degrees))} because it provides a
* more accurate result for angles divisible by 90 degrees.
*
* @param degrees the angle
* @return the cosine of the given angle
*/
public static double dCos(double degrees) {
int dInt = (int) degrees;
if (degrees == dInt && dInt % 90 == 0) {
dInt %= 360;
if (dInt < 0) {
dInt += 360;
}
switch (dInt) {
case 0:
return 1.0;
case 90:
return 0.0;
case 180:
return -1.0;
case 270:
return 0.0;
}
}
return Math.cos(Math.toRadians(degrees));
}
/**
* Returns the sine of an angle given in degrees. This is better than just
* {@code Math.cos(Math.toRadians(degrees))} because it provides a more
* accurate result for angles divisible by 90 degrees.
*
* @param degrees the angle
* @return the sine of the given angle
*/
public static double dSin(double degrees) {
int dInt = (int) degrees;
if (degrees == dInt && dInt % 90 == 0) {
dInt %= 360;
if (dInt < 0) {
dInt += 360;
}
switch (dInt) {
case 0:
return 0.0;
case 90:
return 1.0;
case 180:
return 0.0;
case 270:
return -1.0;
}
}
return Math.cos(Math.toRadians(degrees));
}
}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.math.transform;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.math.MathUtils;
/**
* An affine transform.
@ -244,9 +245,8 @@ public class AffineTransform implements Transform {
}
public AffineTransform rotateX(double theta) {
theta = Math.toRadians(theta);
double cot = Math.cos(theta);
double sit = Math.sin(theta);
double cot = MathUtils.dCos(theta);
double sit = MathUtils.dSin(theta);
return concatenate(
new AffineTransform(
1, 0, 0, 0,
@ -255,9 +255,8 @@ public class AffineTransform implements Transform {
}
public AffineTransform rotateY(double theta) {
theta = Math.toRadians(theta);
double cot = Math.cos(theta);
double sit = Math.sin(theta);
double cot = MathUtils.dCos(theta);
double sit = MathUtils.dSin(theta);
return concatenate(
new AffineTransform(
cot, 0, sit, 0,
@ -266,9 +265,8 @@ public class AffineTransform implements Transform {
}
public AffineTransform rotateZ(double theta) {
theta = Math.toRadians(theta);
double cot = Math.cos(theta);
double sit = Math.sin(theta);
double cot = MathUtils.dCos(theta);
double sit = MathUtils.dSin(theta);
return concatenate(
new AffineTransform(
cot, -sit, 0, 0,