NaN return in code when computing normal vector

nuhnuh
edited July 2016 in Questions about Code

Hey im having trouble figuring out why my code returns NaN when i set m=0 or when i give it the angle =0 . Help would be greatly appreciated i've been trying to figure this out for a while now.

    PVector nvector(float angle){
      float sinc = (m/8)*sin((m/2)*angle);
      float cosc= ((pow(m,2))/16)*cos((m/2)*angle); 

      float g =(-n2*pow(abs(1/a),n2))*pow(cos((m/4)*angle),n2-2)
        +(n3*pow(abs(1/b),n3))*pow(sin((m/4)*angle),n3-2) ;

      float dg = (n2*pow(abs(1/a),n2))*((n2-2))*sinc*pow(cos((m/4)*angle),n2-4)
        +(n3*pow(abs(1/b),n3))*((n3-2))*sinc*pow(sin((m/4)*angle),n3-4);

      float f = pow(abs((1/a)*cos((m/4)*angle)),n2)+ pow(abs((1/b)*sin((m/4)*angle)),n3);

      float df = sinc*g ;

      float d2f = dg*sinc+g*cosc ; 

      float r =pow(f,(-1/n1)); // this is taken care of by the shape function
      float dr = (-1/n1)*pow(f,((-1/n1)-1))*df;

      float d2r =  (1/n1)*((1/n1)+1)*pow(f,((-1/n1)-2))*pow(df,2)+(-1/n1)*pow(f,(-1/n1)-1)*d2f;

      PVector v1 = new PVector(cos(angle),sin(angle)); 
      PVector v3 = new PVector(cos(angle),sin(angle));
      PVector v2 = new PVector(-sin(angle),cos(angle));

      v1.mult(d2r);
      v2.mult((2*dr));
      v3.mult(r);

      PVector M = v1.add(v2);
      PVector N = M.sub(v3);

       return N;
    } 

Answers

  • Sorry that i coulnt get everything into the code box, im new to this forum.

  • The most likely reason is the pow() method which can return a NaN depending on the values passed as arguments. See the API for pow for details.

  • So many undefined variables in that code that we've no way of knowing. Runnable examples are so much more useful.

    If a or b are ever 0 then you have divide by 0 problems.

  • nuhnuh
    edited July 2016

    //This is the runnable code koogs ^-^

                    float x;
                    float y;
                    int a = 1;
                    int b = 1;
                    float n1 = 1;
                    float n2 = 1; 
                    float n3 = 1;
                    float m = 1;
                    float s=m;
                    int radius = 100;
                    float inc = 0;
                    int npoints= 10 ; 
                    void setup() {
    
                  size(600,600);
                }
    
                  float supershape(float angle){
    
                float f1 = (1/a)*cos(angle*m/4); // part one of the function 
                f1=abs(f1);
                f1=pow(f1,n2);
    
                float f2 = (1/b)*sin(angle*s /4);
                f2=abs(f2);
                f2=pow(f2,n3);
    
                float f3= f1 + f2 ; 
                f3 = pow(f3,1/n1); 
    
                return 1/f3;
                  }
    
    
    
                 PVector nvector(float angle){
    
                 float sinc = (m/8)*sin((m/2)*angle);
                   float cosc= ((pow(m,2))/16)*cos((m/2)*angle);
                    float g =(-n2*pow(abs(1/a),n2))*pow(cos((m/4)*angle),n2-2)+(n3*pow(abs(1/b),n3))*pow(sin((m/4)*angle),n3-2) ;
                    float dg = (n2*pow(abs(1/a),n2))*((n2-2))*sinc*pow(cos((m/4)*angle),n2-4)+(n3*pow(abs(1/b),n3))*((n3-2))*sinc*pow(sin((m/4)*angle),n3-4);
                    float f = pow(abs((1/a)*cos((m/4)*angle)),n2)+ pow(abs((1/b)*sin((m/4)*angle)),n3);
                    float df = sinc*g ;
                    float d2f = dg*sinc+g*cosc ; 
                    float r =pow(f,(-1/n1)); // this is taken care of by the shape function
                    float dr = (-1/n1)*pow(f,((-1/n1)-1))*df;
                    float d2r =  (1/n1)*((1/n1)+1)*pow(f,((-1/n1)-2))*pow(df,2)+(-1/n1)*pow(f,(-1/n1)-1)*d2f;
    
                   PVector v1 = new PVector(cos(angle),sin(angle)); 
                   PVector v3 = new PVector(cos(angle),sin(angle));
                   PVector v2 = new PVector(-sin(angle),cos(angle));
                   v1.mult(d2r);
                   v2.mult((2*dr));
                   v3.mult(r);
                   PVector M = v1.add(v2);
                   PVector N = M.sub(v3);
    
                    return N;
    
                  }
    
    
                void draw() {
                  background(0);
                 //m+=1;
                 //s=m;
                  inc = 2*PI/npoints ; // the increments a multiple of pi
                println(pow(1,0));
                  pushMatrix() ;
    
                    translate(width/2,height/2);
                  stroke(255);
                  noFill();
    
    
                   beginShape();
                  for(float theta=0; theta < 2*PI; theta+=inc) {
                   float r= supershape(theta);
                    x= radius*r*cos(theta);
                    y= radius*r*sin(theta);
    
                    vertex(x,y); 
                            pushMatrix();
                  translate(x,y);
                  rotate(nvector(2).heading2D());
                  //print(nvector(2));
                  float len  = 10; 
                 line(0,0,len,0);
    
                  popMatrix();
    
                  }
                  endShape(CLOSE);
    
    
    
                popMatrix();
                }
    
  • Answer ✓

    As I said before the only function that is likely to create a NaN is pow(n, e) looking at the documentation (which you could have done) shows that

    if n is finite and less than zero and e is finite and not an integer it returns NaN.

    There appear to be several calls to pow where this might be the case but YOU need to check them out. Use println to display the values of n and e or step through your code to find out where it goes wrong.

  • nuhnuh
    edited July 2016

    Im checking that at the moment, I just posted the full cod just incase, it seems to be some thing to do with pow if i set that the value should be manually in the case of m=0 the code works. I found it thank you quark! line 40 seems to some how output infinity.

  • ctrl-t in the processing editor will indent your code nicely.

    and a sentence or two explaining what the block of maths is trying to do wouldn't go amiss.

    the above code doesn't fail for me, even with m = 0 and / or angle = 0

  • nuhnuh
    edited July 2016

    The code still runs just it doesnt display the normal vectors. what the math is trying to do in the nvector section is function which computes the normal vector to a super shape (http://paulbourke.net/geometry/supershape/). But for m=0; the vectors are not visible since there is a divide by zero occurring and when angle is 0 theres a divide by zero on the first point so it misses out that normal vector. Normal vectors should appear as lines. Im hopping my derivation of the normal vecotor is correct ive checked it several times. Any help on this matter would be appreciated, the problem occurs 40 and 41 were were there is a sine ^ (n-4 or 2) which out puts infinity.

  • by normal vector, do you mean a vector perpendicular to the shape at the given point? because those look wrong to me - some of them are pointing inside and some are outside.

  • yeah a vector perpendicular to the shape at a given point, do you think my math is wrong, how can you tell if some are pointing in and out if they are only line segments? I asked a question on stack exchange to check my calculation but Ill give the link since I have written out the equation in full there:

    http://math.stackexchange.com/questions/1868442/super-shape-formula-normal-vector-gives-wrong-answer-for-the-case-of-a-ellipse

Sign In or Register to comment.