在processing中通过贝塞尔曲线作图

mac2026-08-20  2

一般的processing函数只能绘制规则的图像或线条,但是想要较为精细的作图就比较困难,为了画出较为精细的图画,我们可以通过贝塞尔函数的代码,通过点和切线来获取线条的贝塞尔函数,[如图所示,a可以添加点,z可以减少点,点最少不能少于两个,但是每次减少或者添加点的时候,会将原有点的位置打乱,所以在每次获取线条之前,需要确定需要多少个点,线条获取完成后,按“p”打印线条的贝塞尔函数。

贝塞尔函数代码

只需要修改代码中图片的路径。

int numNodes = 4; int vertices; boolean vis = true; Node[] Nodes; PFont pixel; float m = 100.0; PImage img; void setup(){ img = loadImage("b.jpeg"); vertices = 0; Nodes = new Node[numNodes]; textSize(15); textAlign(CENTER); ellipseMode(CENTER); size(900, 900); smooth(); for (int i = 0; i < numNodes; i++){ String numNode = nfs(i, 0); // make string one decimal #### Nodes[i] = new Node(m+random(width-(2*m)), m+random(height-(2*m)), numNode); float num = float(i)/3.0; // see if i is a multiple of three if ((i/3) == num){ Nodes[i].col = #FF7040; // If multiple of 3 means a vertex, so give it another color vertices += 1; // Count the vertices; } } } void draw(){ background (255); image(img,0,0); texto(); noFill (); // Draw a Bezier curve by all the nodes .... in 3 strokeWeight (3); stroke (0); beginShape (); vertex (Nodes[0].x, Nodes[0].y); // start at zero for (int i = 1; i < (numNodes - 2); i+=3){ bezierVertex (Nodes[i].x, Nodes[i].y, Nodes[i+1].x, Nodes[i+1].y, Nodes[i+2].x, Nodes[i+2].y); } endShape (); if (vis) { strokeWeight (0.5); // haga las líneas de control stroke (100); for (int i = 1; i < (numNodes - 2); i+=3){ line (Nodes[i-1].x, Nodes[i-1].y, Nodes[i].x, Nodes[i].y); line (Nodes[i+1].x, Nodes[i+1].y, Nodes[i+2].x, Nodes[i+2].y); } } for (int i = 0; i < numNodes; i++){ String numNode = nfs(i, 1); Nodes[i].render (); } // fill(255); // loadPixels(); // color c = pixels[mouseY*width+mouseX]; // text("("+int(red(c))+","+int(green(c))+","+int(blue(c))+")",1000,60); text(mouseX+" "+mouseY,mouseX+20,mouseY-20); } void mouseReleased(){ for (int i = 0; i < numNodes; i++){ Nodes[i].over = false; } } void mouseDragged(){ for (int i = 0; i < numNodes; i++){ if (Nodes[i].over == true){ Nodes[i].x = mouseX; Nodes[i].y = mouseY; for (int j = 0; j < numNodes; j++){ if (j != i){ Nodes[j].over = false;} } } } } void keyPressed() { if (key == 'a') { numNodes += 3; setup (); } //if (key == 'a') if (key == 'z' && numNodes > 4) { numNodes -= 3; setup (); } //if (key == 'z' && numNodes > 4) if (key == 'p') { // loadPixels(); // color c = pixels[mouseY*width+mouseX]; // println("new Color("+int(red(c))+","+int(green(c))+","+int(blue(c))+");"); println("beginShape();"); for (int i = 0; i < numNodes-1; i++) { if(i==0){ println("vertex(" + int(Nodes[i].x) +","+ int(Nodes[i].y ) +");"); println("bezierVertex("+int(Nodes[i+1].x) +","+ int(Nodes[i+1].y ) +","+int(Nodes[i+2].x) +","+ int(Nodes[i+2].y )+","+int(Nodes[i+3].x) +","+ int(Nodes[i+3].y )+");"); }else if(i%3==0){ println("bezierVertex("+int(Nodes[i+1].x) +","+ int(Nodes[i+1].y ) +","+int(Nodes[i+2].x) +","+ int(Nodes[i+2].y )+","+int(Nodes[i+3].x) +","+ int(Nodes[i+3].y )+");"); } } println("endShape();"); } if (key == 'v') { println("beginShape();"); for (int i = 0; i < numNodes; i++) { if(i%3==0)println("vertex(" + int(Nodes[i].x) +","+ int(Nodes[i].y ) +");"); } println("endShape();"); } } class Node { float x, y; float d = 24; String num; boolean over; color col; Node (float _x, float _y, String _num) { x = _x; y = _y; num = _num; over = false; col = #D3FF95; } //Node (float _x, float _y, String _num) void update() { float dis = dist(mouseX, mouseY, x, y); if (dis <= d/2){ over = true; } else { over = false; } } //void update() void draw() { if (over) { strokeWeight (3); stroke (0); } //void draw() else { stroke (100); strokeWeight (1); } //else fill (col); ellipse (x,y, d, d); fill (0); text (num, x-d/4, y+4); text (int( x)+","+int(y), x+10, y+29); } //void draw() void render() { update (); if (vis){ draw(); } } //void render() } //class Node void texto() { fill (0); textSize(width*0.03); text ("Bezier", width/2, 20); String t = "press 'a' to add Nodes, 'z' remove Nodes 'p' print Nodes"; text (t, width/2, height-45); fill (#FF7040); text (vertices +" Nodes "+(numNodes-vertices)+ " Controls" , width/2, height-10); } //void texto()

将获取的贝塞尔函数代码带入processing程序,同时再寻找相近的颜色进行填充,要注意函数绘图的顺序。 和原图的颜色还是有一些区别。

void setup(){ size(1000,1000); } void draw(){ background(0); fill(255,241, 0); beginShape(); vertex(348,787); bezierVertex(300,797,316,794,261,807); bezierVertex(258,786,260,785,253,773); bezierVertex(227,776,229,777,209,779); bezierVertex(206,752,201,736,202,706); bezierVertex(140,725,159,732,96,745); bezierVertex(87,681,67,663,76,557); bezierVertex(157,539,127,530,287,524); endShape(); fill(160,82,45); beginShape(); vertex(332,252); bezierVertex(243,244,201,225,27,224); bezierVertex(52,305,173,382,243,411); endShape(); beginShape(); vertex(561,213); bezierVertex(594,165,729,50,789,60); bezierVertex(754,192,722,241,691,286); endShape(); fill(255,241, 0); beginShape(); vertex(711,538); bezierVertex(785,403,740,353,690,289); bezierVertex(712,275,715,251,731,215); bezierVertex(718,146,692,128,642,128); bezierVertex(606,151,583,192,557,215); bezierVertex(482,198,402,212,330,249); bezierVertex(277,240,241,240,192,232); bezierVertex(146,267,123,302,152,358); bezierVertex(183,375,205,398,240,415); bezierVertex(226,500,238,518,278,572); endShape(); fill(255,128,0); beginShape(); vertex(355,534); bezierVertex(372,504,384,462,309,453); bezierVertex(247,472,249,505,277,530); endShape(); beginShape(); vertex(747,421); bezierVertex(746,466,741,476,704,478); bezierVertex(677,465,668,457,671,420); bezierVertex(676,382,705,357,743,386); endShape(); fill(255,241, 0); beginShape(); vertex(324,516); bezierVertex(309,490,290,499,299,524); bezierVertex(287,499,268,518,274,534); bezierVertex(251,578,252,611,289,652); bezierVertex(256,727,251,807,332,836); bezierVertex(316,879,406,892,408,835); bezierVertex(468,815,495,851,534,856); bezierVertex(512,923,623,901,617,858); bezierVertex(660,818,690,801,709,704); bezierVertex(763,633,794,625,794,533); bezierVertex(807,506,797,499,778,499); bezierVertex(778,475,768,472,750,497); bezierVertex(733,502,720,513,712,533); endShape(); fill(237,145,33); beginShape(); vertex(559,394); bezierVertex(582,453,582,483,509,500); bezierVertex(395,503,411,451,426,428); endShape(); fill(255,241, 0); beginShape(); vertex(559,388); bezierVertex(539,406,525,413,488,408); bezierVertex(475,427,436,427,417,413); endShape(); fill(160,82,45); beginShape(); vertex(265,722); bezierVertex(307,699,314,699,277,691); endShape(); beginShape(); vertex(275,777); bezierVertex(291,759,300,748,268,742); endShape(); fill(255,241, 0); beginShape(); vertex(320,443); bezierVertex(415,357,383,387,313,378); endShape(); beginShape(); vertex(653,369); bezierVertex(550,359,575,361,649,320); endShape(); beginShape(); vertex(503,367); bezierVertex(486,364,485,360,470,373); endShape(); beginShape(); vertex(335,531); bezierVertex(294,542,295,551,319,559); endShape(); beginShape(); vertex(737,518); bezierVertex(762,511,777,519,748,546); endShape(); beginShape(); vertex(358,853); bezierVertex(362,857,362,871,360,873); endShape(); beginShape(); vertex(383,847); bezierVertex(386,856,383,850,389,871); endShape(); beginShape(); vertex(542,889); bezierVertex(545,877,545,883,557,865); endShape(); beginShape(); vertex(574,893); bezierVertex(578,881,585,871,586,871); endShape(); }

之后再在图片上加入一点小小动态,是图片不那么单调 直接打开图片时爱心不显示,按下鼠标时爱心才会显示,松开后爱心再次消失。 在draw()函数中写下代码

ortho(-width/2, width/2, -height/2, height/2); // Same as ortho() background(0,0,0); int cubesize=10; fill(249,37,72); angle += 0.02; int temp=-7*cubesize/2; int gap=y/8-cubesize*3; if(mousePressed){ pushMatrix(); translate(x/8*7,y/4+gap,0); rotateY(-angle); rotateY(-4*PI/6); translate(temp,0,0); drawlove(cubesize); popMatrix(); }

然后定义drawlove函数

for(int i=0;i<7;i++) { for(int j=0;j<6;j++) { if(j==0) { pushMatrix(); translate(cubesize*1,0,0); box(cubesize); popMatrix(); pushMatrix(); translate(cubesize*2,0,0); box(cubesize); popMatrix(); pushMatrix(); translate(cubesize*4,0,0); box(cubesize); popMatrix(); pushMatrix(); translate(cubesize*5,0,0); box(cubesize); popMatrix(); } if(j==1||j==2) { pushMatrix(); translate(i*cubesize,j*cubesize,0); box(cubesize); popMatrix(); } if(j==3&&i>0&&i<6) { pushMatrix(); //translate(i*cubesize,0,j*cubesize); translate(i*cubesize,j*cubesize,0); box(cubesize); popMatrix(); } if(j==4&&i>1&&i<5) { pushMatrix(); translate(i*cubesize,j*cubesize,0); box(cubesize); popMatrix(); } if(j==5&&i==3) { pushMatrix(); translate(i*cubesize,j*cubesize,0); box(cubesize); popMatrix(); } } }

总体上来说,这个皮卡丘做的很简单,还有很多改进的空间。

最新回复(0)