matthijs124 wrote ...

2017/11/14

## Only getting Math.atan() results in a specific area

matthijs124

2017/11/14

I am trying to move a lightsaber (which is in this case still named "NPC") around the player in half a circle. I already have it so it looks like the "Man" (the player) is swinging the lightsaber in half a circle. The problem is, he only swings is downward. I want it to be that he swings it in the direction of your cursor. I think I know how -> I just have to move the existing "half arc" along the unit circle. It is currently only the bottom half of the unit circle. I made something to calculate the slope ("rc" and "rchoek") of the line between the coordinates of the player and the middle of the lightsaber(the "NPC") For this, I calculate the slope between the points, and use the inverse tangent to calculate the angle between the two points (radian angle on the unit circle). If I know that angle, I can adjust the arc which the lightsaber moves along the unit circle to another position. The problem is: The calculation of the inverse tangent (arctan) is acting really weirdly. I only get results in the bottom and top fourth of the circle (45 degrees). That means, the sides of the circle just get the results zero. Calculating it by hand, it should always output a number other than 0 except for when the slope is 0, and it only is when the Y values of the two are the same, so I am confused as of why this does not work. This is a rough visualisation of what the problem is: Excuse my drawing skills. I get NO results of atan in the sides, even when the values which I fill into the function are different than 0. I ONLY get results in the blue areas. the code:
```import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class NPC extends Actor
{
private double i = 0;
private int xi;
private double xd;
private int yi;
private double yd;
private boolean forward = true;
private int Xmin;
private int Xmax;
private int Ymax;
private double speed = 0.02;
private int startX, startY;
private double rc;
private double rchoek;

public NPC()
{
getImage().scale(100,80);

}

public void act()
{
int startX = getManX();
int startY = getManY();

rc = getRC();
double rchoek = Math.atan(rc);
System.out.println(rchoek);
if (forward == true){
i = i + speed;
}
if (i > 3.14159265359 && forward == true) {
forward = false;
Xmin = getLocationX();
Ymax = getLocationY();
}
if (forward == false){
i = i - speed;
}
if (i < 0 && forward == false) {
forward = true;
Xmax = getLocationX();
Ymax = getLocationY();
}

int xi = (int) xd;
int yi = (int) yd;
setLocation(xi + startX, yi + startY);
turnTowards(getManX(), getManY());
}

public int getLocationX()
{
return(this.getX());
}

public int getLocationY()
{
return(this.getY());
}

public int getManX()
{
Man man = getWorld().getObjects(Man.class).get(0);
return man.getXLoc();
}

public int getManY()
{
Man man = getWorld().getObjects(Man.class).get(0);
return man.getYLoc();
}

public int getRC()
{
int xa = 0, xb = 0, ya = 0, yb = 0;
if ( getManX() != getX() ){
if (getManX() >= getX()){
xb = getManX();
xa = getX();
}
if (getX() >= getManX()){
xa = getManX();
xb = getX();
}
if (getManY() >= getY()){
yb = getManY();
ya = getY();
}
if (getY() >= getManY()){
ya = getManY();
yb = getY();
}
return ( (yb - ya) / (xb - xa) );
} else {
return 0;
}
}
}```
danpost

2017/11/14

The 'getRC' method needs to return a 'double' value (and the calculations within it cannot be allowed to lose precision due to 'int' operations.
Super_Hippo

2017/11/14

One problem could be that your getRC method returns an int and not a double. I would also suggest to use the atan2 method.