Processingには曲線を描画するメソッドが2種用意されています。一つはベジェ(Bezier)曲線でイラストレータのペンツールでも利用されている曲線です。他は、Catsmull-Romのスプライン曲線で、連続する点をつなぐ曲線です。
size(300, 150); noFill(); stroke(255, 102, 0); line(20, 85, 60, 10); line(60, 10, 200, 20); line(200, 20, 250, 85); stroke(0, 0, 0); bezier(20, 85, 60, 10, 200, 20, 250, 85);実行結果
void setup() { background(250); size(300, 150); noFill(); stroke(255, 102, 0); line(20, 85, 60, 10); line(60, 10, 180, 130); line(180, 130, 250, 85); stroke(0, 0, 0); bezier(20, 85, 60, 10, 180, 130, 250, 85); }実行結果
L(t) = P*t + Q*(1-t) t=0.0..1.0で表現できます。P,Qは座標(x,y)を示すベクタ(値の組)で、tは0から1までの少数です。
Lx(t) = Px*t + Qx*(1-t) Ly(t) = Py*t + Qy*(1-t)と座標毎に計算します。
//Point クラスの定義 class Point{ int x; int y; //引数なしのコンストラクター Point(){ }; //引数付きのコンストラクター Point(int x, int y){ //左の x はこのクラスの x、右辺は引数の x this.x=x; this.y=y; } } //ベジェクラスの定義 class BezierC { Point[] bc = new Point[4]; //コンストラクター BezierC(Point [] bc) { for(int i=0;i<4;i++){ this.bc[i]=new Point(); this.bc[i].x =bc[i].x; this.bc[i].y =bc[i].y; } } //4点を円で表示 void poly(){ for(int i=0;i<4;i++){ ellipse(bc[i].x,bc[i].y,5,5); } } //曲線表示 void curve() { double t; Point bp=new Point(); bp.x=bc[0].x; bp.y=bc[0].y; Point np=new Point(0,0) ; for (t=0.0;t<=1.001;t=t+0.05) { np.x=(int)(bc[0].x*(1-t)*(1-t)*(1-t) + 3*bc[1].x*t*(1-t)*(1-t) + 3*bc[2].x*t*t*(1-t) + bc[3].x*t*t*t); np.y=(int)(bc[0].y*(1-t)*(1-t)*(1-t) + 3*bc[1].y*t*(1-t)*(1-t) + 3*bc[2].y*t*t*(1-t) + bc[3].y*t*t*t); line(bp.x,bp.y,np.x,np.y); bp.x=np.x; bp.y=np.y; } /* stroke(0,255,0); bezier(bc[0].x,bc[0].y,bc[1].x,bc[1].y, bc[2].x,bc[2].y,bc[3].x,bc[3].y); */ } }
//ベジェ曲線の表示 //制御点をマウスで移動可能 Point[] bp = new Point[4]; BezierC bz; int fp; void setup() { bp[0] = new Point(10, 60); bp[1] = new Point(30, 10); bp[2] = new Point(80, 15); bp[3] = new Point(120, 60); bz = new BezierC(bp); fp=-1; size(150,150); } void draw(){ background(200); noFill(); stroke(0,0,0); bz.poly(); stroke(255,0,0); bz.curve(); } //マウスボタンが押された void mousePressed(){ double dx; for(int i=0;i<4;i++){ dx =sqrt( (bz.bc[i].x-mouseX)* (bz.bc[i].x-mouseX) + (bz.bc[i].y-mouseY)* (bz.bc[i].x-mouseY)); if(dx<15){ fp=i; println(fp); } } println(fp); } //マウスがドラッグされた void mouseDragged(){ if(fp>=0){ bz.bc[fp].x = mouseX; bz.bc[fp].y = mouseY; } } //マウスボタンが離された void mouseReleased(){ fp=-1; }