UF1 - Basic Trigonometrics
per Jordi Farrero
—
darrera modificació
2020-03-25T14:54:47+01:00
public class TrigonometryBasics
{
public static int DONT_INTERSECT = 0;
public static int COLLINEAR = 1;
public static int DO_INTERSECT = 2;
private static float x =0, y=0;
//
public static double CalcAngle2(Line line1,Line line2)
{
//
double a = (float)line1.getX1() - line1.getX2();
double b = (float)line1.getX2() - line1.getY2();
double c = (float)line2.getX1() - line2.getY1();
double d = (float)line2.getX2() - line2.getY2();
//
double cos_angle , angle;
double mag_v1 = Math.sqrt(a*a + b*b);
double mag_v2 = Math.sqrt(c*c + d*d);
//
cos_angle = (a*c + b*d) / (mag_v1 * mag_v2);
angle = Math.acos(cos_angle);
angle = angle * 180.0 / 3.14159; // convert to degrees ???
//
return angle;
}
//
public static int intersect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
{
float a1, a2, b1, b2, c1, c2;
float r1, r2 , r3, r4;
float denom, offset, num;
// Compute a1, b1, c1, where line joining points 1 and 2
// is "a1 x + b1 y + c1 = 0".
a1 = y2 - y1;
b1 = x1 - x2;
c1 = (x2 * y1) - (x1 * y2);
// Compute r3 and r4.
r3 = ((a1 * x3) + (b1 * y3) + c1);
r4 = ((a1 * x4) + (b1 * y4) + c1);
// Check signs of r3 and r4. If both point 3 and point 4 lie on
// same side of line 1, the line segments do not intersect.
if ((r3 != 0) && (r4 != 0) && same_sign(r3, r4)){
return DONT_INTERSECT;
}
// Compute a2, b2, c2
a2 = y4 - y3;
b2 = x3 - x4;
c2 = (x4 * y3) - (x3 * y4);
// Compute r1 and r2
r1 = (a2 * x1) + (b2 * y1) + c2;
r2 = (a2 * x2) + (b2 * y2) + c2;
// Check signs of r1 and r2. If both point 1 and point 2 lie
// on same side of second line segment, the line segments do
// not intersect.
if ((r1 != 0) && (r2 != 0) && (same_sign(r1, r2))){
return DONT_INTERSECT;
}
//Line segments intersect: compute intersection point.
denom = (a1 * b2) - (a2 * b1);
if (denom == 0) {
return COLLINEAR;
}
if (denom < 0){
offset = -denom / 2;
}
else {
offset = denom / 2 ;
}
// The denom/2 is to get rounding instead of truncating. It
// is added or subtracted to the numerator, depending upon the
// sign of the numerator.
num = (b1 * c2) - (b2 * c1);
if (num < 0){
x = (num - offset) / denom;
}
else {
x = (num + offset) / denom;
}
num = (a2 * c1) - (a1 * c2);
if (num < 0){
y = ( num - offset) / denom;
}
else {
y = (num + offset) / denom;
}
// lines_intersect
return DO_INTERSECT;
}
private static boolean same_sign(float a, float b)
{
return (( a * b) >= 0);
}
public static float getTargetAngle(float startX, float startY, float startAngle, float targetX, float targetY){
float dX = targetX - startX;
float dY = targetY - startY;
//find the coordinates of the waypoint in respect to the centre of the sprite
//with the scene virtually rotated so that the sprite is pointing at 0°
float cos = (float) Math.cos( Math.toRadians(-startAngle));
float sin = (float) Math.sin( Math.toRadians(-startAngle));
float RotateddX = ((dX * cos) - (dY * sin));
float RotateddY = ((dX * sin) + (dY * cos));
//Now get the angle between the direction the sprite is pointing and the
//waypoint
float angleRad = (float) Math.atan2(RotateddY, RotateddX);
float angleDeg = (float) Math.toDegrees(angleRad);
return angleDeg;
}
/**
* Calculates the angle from centerPt to targetPt in degrees.
* The return should range from [0,360), rotating CLOCKWISE,
* 0 and 360 degrees represents NORTH,
* 90 degrees represents EAST, etc...
*
* Assumes all points are in the same coordinate space. If they are not,
* you will need to call SwingUtilities.convertPointToScreen or equivalent
* on all arguments before passing them to this function.
*
* @param centerPt Point we are rotating around.
* @param targetPt Point we want to calcuate the angle to.
* @return angle in degrees. This is the angle from centerPt to targetPt.
*/
public static double calcRotationAngleInDegrees(Point centerPt, Point targetPt)
{
// calculate the angle theta from the deltaY and deltaX values
// (atan2 returns radians values from [-PI,PI])
// 0 currently points EAST.
// NOTE: By preserving Y and X param order to atan2, we are expecting
// a CLOCKWISE angle direction.
double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x);
// rotate the theta angle clockwise by 90 degrees
// (this makes 0 point NORTH)
// NOTE: adding to an angle rotates it clockwise.
// subtracting would rotate it counter-clockwise
theta += Math.PI/2.0;
// convert from radians to degrees
// this will give you an angle from [0->270],[-180,0]
double angle = Math.toDegrees(theta);
// convert to positive range [0-360)
// since we want to prevent negative angles, adjust them now.
// we can assume that atan2 will not return a negative value
// greater than one partial rotation
if (angle < 0) {
angle += 360;
}
return angle;
}
public static double angleBetween2Lines(Line line1, Line line2)
{
//Give three points on a plane, P0, P1 and P2, form a line from P0 to P1
//and a line from P0 to P2.
float l1x = line1.getX1() - line1.getX2();
float l1y = line1.getY1() - line1.getY2();
float l2x = line2.getX2() - line1.getX2();
float l2y = line2.getY2() - line1.getY2();
double ang1 = Math.atan2(l1y,l1x);
double ang2 = Math.atan2(l2y,l2x);
return Math.abs(Math.toDegrees(ang2-ang1));
}
}