FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Programming Questions & Help
   Programs
(Moderators: fry, REAS)
   weird trig problem
« Previous topic | Next topic »

Pages: 1 
   Author  Topic: weird trig problem  (Read 370 times)
wilson


weird trig problem
« on: Apr 12th, 2004, 4:32am »

hi.  
 
So I'm doing this bigger project, but am trying to test this bit of code to make sure it works before I move on.  Basically, I want to have individual nodes reposition themselves according to the perspective of a single entity - in the project, this will be a user, in the test code, it's a rectangle.  For example, there are a bunch of nodes positioned around a center point.  When the user moves forward or backward, these nodes move closer / farther away along the y-axis.  When the user turns (using the A or D keys, the nodes move closer / farther away from the user's vision -- which means they are basically just rotating around a circle with the center point the x,y of the user (which in this case happens to be the center of the stage).
 
But I'm having a slight problem making this work.  A quick test of the below code should make clear what I want to have happen.  And everything is working as long as the angle of the node is between 0-180 degrees.  However, if you try and position a node in front of you (180-360 degrees, assuming 270 degrees is right in front of the you) by moving it along the y axis (with w and s keys), then it seems to flip the axis.  
 
This seems like it should be a simple problem, but I'm having a really difficult go at it.
 
If there is someone out there who sees a solution, I'd be ever so appreciative of a reply.
 
Code is below.  Thanks for any help in advance.
 
_Will
 
float i; //angle
color c; //color of circle
float x, y, track_x, track_y; // x, y are stage locations,  
     //track_x, track_y are locations relative to the center of the circle (the square)
boolean moveY; // true when user is moving along the y axis (using w and s keys)
float radius, convert; //radius is the radius between circle and the center square
String direction; // to tell showDirections which kind of arrow to draw
 
void setup()
{
  size(400, 400);
  i=90;  //start w/ radius of 90 degrees
  c=color(0, 0, 0);
  background(255);
  moveY = true; //assume we are moving forward initially
  convert = radians(i);  //convert i degrees to radians to work with
  radius = 50; //initial radius of 50 px
  track_x = radius * cos(convert);  //grab x position from center
  track_y = radius * sin(convert);  //y position from center
  x = width/2+track_x; //x position on stage
  y = height/2+track_y; //y position on stage
}
 
void loop()
{
  //static stuff
  background(255);
  stroke(0);
  fill(0);
  rectMode(CENTER_RADIUS);
  ellipseMode(CENTER_RADIUS);
  rect(200, 200, 5, 5); //draw out a rectangle at center -- represents the user
   
  showDirection(direction); // pass direction to a function  
        // that draws out the appropriate arrow
 
  //trig stuff
  noStroke();
  fill(c);
 
  radius = dist(width/2, height/2, x, y);  // calculate radius
 
  if (moveY) {  //if we are moving forwards or backwards along the y axis
   
    //use cosA=b/c
    float temp = track_x/radius;
    //grab updated angle
    i = degrees(float(Math.acos(temp)));
    //update ellipse data in relation to center point
    convert = radians(i);
    track_x = radius * cos(convert);
    track_y = radius * sin(convert);
    //draw out ellipse
    ellipse(x, y, 5, 5);
 
  } else {  
 //reposition the ellipse according to the current radius and angle
 convert = radians(i);
 track_x = radius * cos(convert);
 track_y = radius * sin(convert);
 //update stage position
 x = width/2+track_x;
 y = height/2+track_y;
 ellipse(x, y, 5, 5);
  }
   
  keyPressed();  
 
}
 
void mousePressed() {
  println(i);
}
 
//handles the key stuff, moving forward, backward, or turning left or right
void keyPressed()  
{
  if (key == 'a') {
    if (i<=0) {
 i=360;
    } else {
 i-=1;
    }
    direction="LEFT";
    moveY=false;
  }
 
  if (key == 'd') {
    if (i>=360) {
 i=0;
    } else {
 i+=1;
    }
    direction="RIGHT";
    moveY=false;
  }
  if (key == 'w') {
    y+=2;
    direction="FORWARDS";
    moveY=true;
  }
  if (key == 's') {
    y-=2;
    direction="BACKWARDS";
    moveY=true;
  }
}
 
//draws out helper arrows that signal current direction / rotation
void showDirection(String dir)  
{
  if (dir=="NONE") {
    rect(10, 10, 10, 10);
  }
  if (dir=="LEFT") {
    line(10, 20, 50, 20);
    line(40, 10, 50, 20);
    line(40, 30, 50, 20);    
  }
  if (dir=="RIGHT") {
    line(10, 20, 50, 20);
    line(20, 10, 10, 20);
    line(20, 30, 10, 20);    
  }
  if (dir=="FORWARDS") {
    line(10, 20, 20, 10);
    line(20, 10, 30, 20);
    line(20, 10, 20, 50);
  }
  if (dir=="BACKWARDS") {
    line(20, 10, 20, 50);
    line(10, 40, 20, 50);
    line(30, 40, 20, 50);
  }
   
 
 
}
 
 
 
 
arielm

WWW
Re: weird trig problem
« Reply #1 on: Apr 12th, 2004, 10:27am »

not tested, just an intuition: try to use atan2() instead of acos() or asin()
 

Ariel Malka | www.chronotext.org
wilson


Re: weird trig problem
« Reply #2 on: Apr 12th, 2004, 4:56pm »

hm.  atan2 doesn't seem to work, although I'm not sure exactly why.
 
wilson


Re: weird trig problem
« Reply #3 on: Apr 12th, 2004, 5:11pm »

also... the var track_x (which holds the x position of the ellipse relative to the center point of the stage) seems to be inconsistently positive or negative... not sure why that is, but it may be a problem -- and abs(track_x) is giving me a NaN at certain points...
 
arielm

WWW
Re: weird trig problem
« Reply #4 on: Apr 12th, 2004, 5:56pm »

i didn't meant to replace acos() as it is with atan2(),
 
rather:
 
you use the "cosA=b/c" pattern to find out an angle, so i meant that you have to adapt this pattern to "tanA=a/b" and then: A = atan2(b, a)
 
all this because acos() and asin() are well-known trouble makers (i.e. producing NaN, aka errors, at some angles), also atan2() is always returning a "full angle" (i.e. no headache with signs, directions, etc...)
 
another tip: you don't have to convert to degrees() and then back to radians()... just keep everything in radians...
 

Ariel Malka | www.chronotext.org
wilson


Re: weird trig problem
« Reply #5 on: Apr 12th, 2004, 7:07pm »

thanks.  I changed the angle calculation to:
 
i = atan2(y-(height/2), x-(width/2));
 
(substracting height/2, width/2 to position according to the 0, 0 position of the coordinate origin -- could also prob. just use translate)
 
so this works in most cases, but also, by what I can tell, yeilds random errors at some points...
 
thanks for all your help -- any other suggestions would be much appreciated.
 
code now looks like:
 
  //not yeilding a negative track_y
  if (moveY) {  //if we are moving forwards or backwards along the y axis
   
    //use tanA=a/b
    //grab updated angle  
 
    i = atan2(y-(height/2), x-(width/2));
 
    //update ellipse data in relation to center point
    track_x = radius * cos(i);
    track_y = -(radius * sin(i));
    //draw out ellipse
    ellipse(x, y, 5, 5);
 
  } else {  
  //reposition the ellipse according to the current radius and angle
 track_x = radius * cos(i);
 track_y = radius * sin(i);
 //update stage position
 x = width/2+track_x;
 y = height/2+track_y;
 ellipse(x, y, 5, 5);
  }
 
wilson


Re: weird trig problem
« Reply #6 on: Apr 12th, 2004, 7:15pm »

update: the above code seems to work, above 180 degrees, when the user is rotating clockwise... but counterclockwise rotation resets angle (i) to 0 degrees.  ugh.
 
 
Pages: 1 

« Previous topic | Next topic »