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));

    }
}