Bezier curve gone awry

Hey there!

I desperately need someone's help. Wanted to understand how bezier curves work with summation and everything (to control a plotter sometime in the not so far future), but it just won't work right.

// number of control points
int points = 4;

// coordinates
int [] xVal = new int [points];
int [] yVal = new int [points];

// curve resolution
int resolution = 300;

void setup() {
  size(600, 600);

  xVal[0] = 150;
  yVal[0] = 150;
  xVal[1] = 150;
  yVal[1] = height-150;
  xVal[2] = width-150;
  yVal[2] = height-150;
  xVal[3] = width-150;
  yVal[3] = 150;
}

void draw() {
  background(0);
  ellipseMode(CENTER);
  fill(255);
  noStroke();

  float incr = 1.0/resolution;

  // execute while 0 <= t <= 1
  for (int k = 0; k< resolution; k++) {
    float t = incr*(float)k;
    float xPos = 0;
    float yPos = 0;

    // summation for every value of t
    for (int i = 0; i < points; i++) {
      xPos += (factorial(points)/(factorial(i)*factorial(points-i))) * (pow(1.0-t, points-i)) * (pow(t, i)) * (xVal[i]);
      yPos += (factorial(points)/(factorial(i)*factorial(points-i))) * (pow(1.0-t, points-i)) * (pow(t, i)) * (yVal[i]);
    }

    fill(t*255);
    ellipse(xPos, yPos, 2, 2);
  }
  // display red bounding box
  for (int i = 0; i< points; i++) {
    stroke(255, 0, 0);
    noFill();
    line(xVal[i], yVal[i], xVal[(i+1)%points], yVal[(i+1)%points]);
  }

  saveFrame("whyyyyyyy.jpg");
  noLoop();
}

int factorial (int counter) {
  int holder = 1;
  for (int f = 1; f <= counter; f++) {
    holder *= f;
  }
  return holder;
}

And the result:

It should start at the left upper corner of the red square and end at the right upper corner. So as variable 't' grows, zero somehow gets involved, and this happens. The number of control points has no effect, neither has the type of variables used. The only way I could make it right was by factoring the whole function and leaving out the summation entirely, but that leaves me with a preset number of control points, which removes all the fun. What do i miss here?

Tagged:

Comments

  • It should start at the left upper corner of the red square

    but xpos = 0 and ypos = 0 in lines 35, 36

  • edited January 2015

    I think they have to be. Tried every other possible value i could think of, they all look similar to this:

    Here they get the coordinates of the first control point, but that results in a completely different problem.

  • but that results in a completely different

    yeah, but it fixes the first problem, the starting at 0, 0. we can go from there...

    Here they get the coordinates of the first control point

    that's standard for beziers. the curve passes through first and last points. first image here: http://en.wikipedia.org/wiki/Bézier_curve

    draw your control points. colour them so you can tell the ordering.

    you can even use the built-in bezier calls to draw a curve you should be approximating.

    lines 40 and 41, is that an integer division?

  • edited January 2015

    SOLVED! So trivial. I'd swear I did this once without success, but...

    How it was:

    xPos += (factorial(points)/(factorial(i)*factorial(points-i))) * (pow(1.0-t, points-i)) * (pow(t, i)) * (xVal[i]);

    And how it is now:

    xPos += (factorial(points-1) / (factorial(points-1-i)*factorial(i))) * (pow(1.0-t, points-1-i)) * (pow(t, i)) * xVal[i];

    Proof:

    Green is the built in bezier() function and the white dots are the coordinates the raw bezier function traced.

    Thanks koogs for your help!

Sign In or Register to comment.