processing 画的自画像(街雄)
这个是老师布置的作业,要画自画像,可是本人自己没有什么突出的特点,死肥宅一个,于是乎画了一个《流汗吧,健身少女》里的训练师街雄,水平不精。
原图:
没错,就是百度上直接拉下来的。最后我后悔画这么写实的了,画个Q版的肯定简单而且好看的多。
我画的:
图像基本都是用贝塞尔曲线描,背景是有难度的,鼠标有两种模式,一种是将离鼠标最近的几个点和鼠标联系起来,另一种是连接起来的同时,离鼠标比较近的点还会向鼠标方向移动。两种模式鼠标点击切换。
先说难受人的画图像过程吧,这个比较简单,就是找点,贝塞尔里的所有的锚点都是可以用ps或者其他工具直接找到点的坐标的,我用的是我朋友在网上找到的一个找点坐标的工具,和ps有点像,所有的线都是用贝塞尔做的,然后调节颜色,边界线粗细这种,然后要记住是那个层在上哪个层在下。下面是基本的例子。是做头发的。
strokeWeight(1);
beginShape();
fill(77,95,107);
vertex(859,0);
bezierVertex(886,28,864,85,981,67);
bezierVertex(950,99,922,91,901,88);
bezierVertex(915,127,915,200,911,231);
bezierVertex(926,257,937,277,961,289);
bezierVertex(925,275,915,271,905,273);
bezierVertex(908,302,924,338,940,358);
bezierVertex(867,328,857,240,844,206);
bezierVertex(837,227,836,242,832,262);
bezierVertex(817,171,809,152,792,115);
bezierVertex(784,179,771,217,733,280);
bezierVertex(729,211,712,150,683,116);
bezierVertex(680,179,668,233,663,262);
bezierVertex(648,161,655,119,642,76);
bezierVertex(628,125,625,188,565,250);
bezierVertex(569,202,574,154,575,116);
bezierVertex(533,249,480,288,454,322);
bezierVertex(446,280,428,248,425,211);
bezierVertex(421,283,427,318,436,354);
bezierVertex(408,320,395,295,393,261);
bezierVertex(394,268,385,288,371,306);
bezierVertex(376,285,378,270,376,258);
bezierVertex(352,326,332,326,311,335);
bezierVertex(347,300,369,234,358,201);
bezierVertex(341,221,314,227,292,214);
bezierVertex(403,198,351,53,384,47);
bezierVertex(343,37,329,24,309,16);
bezierVertex(372,27,396,6,409,-4);
endShape();
//hair
上面的东西也就是工作量大,下面说背景。
背景的难度挺大的,我查了一些资料,然后在人家的工程上改的,但是人家的工程本来就能运行,就是人家的工程就是没有考虑计算量,就会很卡,我优化了一下,下面是关于背景的代码。
全局变量:
int num=300;
float r[]=new float[num];//set points radius
float theta[]=new float[num];
//float theta=30;
PVector v[]=new PVector[num];//random vector
float dst[]=new float[num];//distacne between the point and the mouse
float dst1[]=new float[num];//points between together
float[] easing=new float[num];
float move_dist;
boolean mo=true;//if mouse pressed
(要不是不能用汉字我才不写英文)
setup里:
size(1400, 788);
for(int i=1;i<=num-1;i++)
{
v[i]=new PVector(random(width),random(height));//set points pos
r[i]=random(1,5);//set points radius
move_dist=random(20,40);
theta[i]=random(180)*PI/180;
easing[i]=random(0.06,0.9);
}
frameRate(30);
最开始的size是图像的长宽。
draw里:
background(0,0,0);
fill(255,255,255);
for(int i=1;i<=num-1;i++)
{
v[i]=new PVector(v[i].x+cos(second()+random(20,30))+random(-1,1),v[i].y+sin(second()+random(20,30))+random(-1,1));//set points pos
//r[i]=random(1,5);//set points radius
}
for (int i=1;i<=num-1;i++)
{
noStroke();
ellipse(v[i].x,v[i].y,r[i],r[i]);
dst[i]=dist(mouseX,mouseY,v[i].x,v[i].y);
for (int j=1;j<=num-1;j++)
{
dst1[j]=dist(v[i].x,v[i].y,v[j].x,v[j].y);
if(dst1[j]<=80)
{
stroke(255,255,255);
stroke(255,255-dst[j]);
strokeWeight(1);
line(v[i].x,v[i].y,v[j].x,v[j].y);
}
}
//contact point and point
}
for(int j=1;j<=num-1;j++)
{
if(dst[j]<=80 && mo)
{
stroke(255,255,255);
stroke(255,255-dst[j]);
strokeWeight(1);
line(mouseX,mouseY,v[j].x,v[j].y);
}
if(dst[j]<=150 && !mo){
stroke(255,255,255);
stroke(255,255-dst[j]);
strokeWeight(1);
line(mouseX,mouseY,v[j].x,v[j].y);
v[j]=new PVector(v[j].x+(mouseX-v[j].x)/dst[j],v[j].y+(mouseY-v[j].y)/dst[j]);//
}
}
//contact mouse and p
这些其实认真看都很好看懂,也很简单就能改。mo变量在mousedown里每次取反
随机给每个点的位置,mo对的时候,就直接每个点计算和鼠标的值,到范围就连,把每个连起来的再作为(鼠标)再算一次距离,再连一次。其实原理很简单,然后通过距离把控透明度。
mo取错的时候基本的都没动,就改了一点,让每个直接连起来的点向鼠标移动,做一个类似聚集的感觉。