I have a java code which moves control points (Corner points) according to the mouse movement. I need to modify the code so that it moves the weight points (the points in between the control points) according to the mouse drag.
PGraphics pg;
float scale, dW;
float [][] pt;
float [][] wpt;
boolean pressed;
int selected;
// Bezier curve
int order;
void setup() {
// setup the screen
size(600,400);
pg = createGraphics(600,400);
// scale of the image
scale = 150;
// prepare the Bezier curve
order = 3;
// declare the control polygon
pt = new float[order + 1][3];
// delcare the weight points
wpt = new float[order][3];
// initialize the control polygon
float angle;
int i;
for(i = 0; i <= order; i += 1) {
angle = 1.25*PI-1.5*PI*i/order;
pt[i] = new float[] { 1, cos(angle), sin(angle) };
}
// set mouse to not pressed
pressed = false;
// initialize selected point: nothing = -1
selected = -1;
// initialize delta Weight
dW = 0.05;
}
// convert from world coordinate to image coordinates x
float convertX(float x) {
return 300 + scale*x;
}
// convert from image to world coordinates x
float convertXback(float x) {
return (x - 300)/scale;
}
// convert from world coordinate to image coordinates y
float convertY(float y) {
return 200 - scale*y;
}
// convert from image to world coordinate y
float convertYback(float y) {
return (200 - y)/scale;
}
// draw edge of polygon
void drawLine(float[] p0, float[] p1) {
pg.line(convertX(p0[1]/p0[0]), convertY(p0[2]/p0[0]), convertX(p1[1]/p1[0]), convertY(p1[2]/p1[0]));
}
// draw control polygon
void drawPolygon(float[][] pol, int n) {
for(int i = 0; i < n; i += 1) {
drawLine(pol[i], pol[i+1]);
}
}
// make nice circles around points
void drawPoints(float pol[][], int n) {
for(int i = 0; i <= n; i += 1) {
pg.ellipse(convertX(pol[i][1]/pol[i][0]), convertY(pol[i][2]/pol[i][0]), 8, 8);
}
}
// interpolate two points at value t
float[] interpolate(float[] p0, float[] p1) {
return new float[] { (p0[0]+p1[0])/2, (p0[1]+p1[1])/2, (p0[2]+p1[2])/2 };
}
// compute one step in the deCasteljau algorithm, i is the number of the step (order-i) is the total number of points
float[][] deCasteljauStep(float [][] B, int i) {
float[][] Bnext = new float[order-i][3];
for(int j = 0; j < order-i; j += 1) {
Bnext[j] = interpolate(B[j], B[j+1]);
}
return Bnext;
}
// full deCasteljau algorithm
void deCasteljau(float[][] pol, int level) {
// initialise left and right control polygon
float[][] lPol = new float[order+1][3];
float[][] rPol = new float[order+1][3];
// first and last point remain the same
lPol[0] = pol[0];
rPol[order] = pol[order];
for(int i = 1; i <= order; i += 1) {
pol = deCasteljauStep(pol, i-1);
lPol[i] = pol[0];
rPol[order-i] = pol[order-i];
}
if(level>0) {
deCasteljau(lPol, level-1);
deCasteljau(rPol, level-1);
} else {
drawPolygon(lPol, order);
drawPolygon(rPol, order);
}
}
// move control point
void moveControlPoint() {
if(mousePressed) {
// x and y of mouse in world coordinates
float mx = convertXback(mouseX);
float my = convertYback(mouseY);
// if just pressed go through all control points and select closest one
if(pressed == false) {
pressed = true;
// initialize selected point to be -1
selected = -1;
// variables to keep track of distance
float dist = 999999999;
float dist0;
for(int i=0; i <= order; i += 1) {
// use square of distance instead of distance to minimize computations
dist0 = sq(pt[i][1]/pt[i][0]-mx) + sq(pt[i][2]/pt[i][0]-my);
if(dist0 < dist) {
dist = dist0;
selected = i;
}
}
} // end if pressed
// change the selected control point to mouse location
float w = pt[selected][0];
// change weight
if(keyPressed) {
switch(keyCode) {
case UP:
w += dW;
break;
case DOWN:
w -= dW;
// make sure w is always positive (but not 0)
if(w<=0) {
w = 0.00001;
}
break;
}
}
pt[selected] = new float[] { w, w*mx, w*my };
} else { // end if pressed
pressed = false;
}
}
// calculate weight points
void calcWpt() {
for(int i = 0; i < order; i += 1) {
wpt[i][0] = pt[i][0]+pt[i+1][0];
wpt[i][1] = pt[i][1]+pt[i+1][1];
wpt[i][2] = pt[i][2]+pt[i+1][2];
}
}
void draw() {
// start drawing
pg.beginDraw();
pg.background(200);
pg.fill(200);
// draw control polygon
pg.strokeWeight(2);
drawPolygon(pt, order);
// draw Bezier curve
pg.strokeWeight(4);
deCasteljau(pt,8);
//draw control points
pg.strokeWeight(2);
drawPoints(pt, order);
// calculate the weight points
calcWpt();
pg.strokeWeight(1);
drawPoints(wpt, order-1);
// move selected control point
moveControlPoint();
// end drawing
pg.endDraw();
image(pg,0,0);
}