/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.ilSY-PEYCFx/rev.3161
*
* authors:
* Tiou Lims
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
class Android{
final static float SCALE = 100f / (78 + 183 + 9 + 100);
final static float D_P_XF = (16 * SCALE); //0
final static float D_P_AB = (9 * SCALE);//1
final static float D_P_HB = (9 * SCALE);//2
final static float D_F_W = (49 * SCALE);//3
final static float D_F_H = (78 * SCALE);//4
final static float D_B_W = (108 * SCALE);//5
final static float D_B_H = (183 * SCALE);//6
final static float D_A_W = (48 * SCALE);//7
final static float D_A_H = (146 * SCALE);//8
final static float D_H_W = (108 * SCALE);//9
final static float D_H_H = (100 * SCALE);//10
final static float D_E_R = (10 * SCALE);//11
final static float D_T_D = 60 ; //角度 0~PI/2 逆时针 //12
final static float D_T_W = (18 * SCALE);//13
final static float D_T_H = (37 * SCALE);//14
final static float D_H = D_F_H + D_B_H + D_P_HB + D_H_H;
final static float D_W = D_B_W + D_P_AB + D_A_W ;
final static float[] D_V = {
D_P_XF,
D_P_AB,
D_P_HB,
D_F_W,
D_F_H,
D_B_W,
D_B_H,
D_A_W,
D_A_H,
D_H_W,
D_H_H,
D_E_R,
D_T_D,
D_T_W,
D_T_H,
D_H ,
D_W
};
final static int ret = 12;
float free [] ;
Rect rF, rB, rA,rH ,rE,rT,rS;
class Rect {
/**
* 笛卡尔坐标系
*
*
*/
protected float l, t, r, b;
public Rect() {
}
public void reBound(float x, float y, float w, float h) {
this.l = x;
this.t = (y + h);
this.r = x + w;
this.b = y;
}
void draw(){
rect(l,t,r-l,b-t);
}
}
class Arm extends Rect{
void draw(){
l = this.l;
t = this.t;
r = this.r;
b = this.b;
pushMatrix();
float w = r-l;
float h = b-t;
translate(l+w/2,b-h/2);
rrect(w,-h,{w/2,w/2,w/2,w/2},ret);
popMatrix();
}
}
class Foot extends Rect{
void draw(){
l = this.l;
t = this.t;
r = this.r;
b = this.b;
pushMatrix();
float w = r-l;
float h = b-t;
translate(l+w/2,b-h/2);
rrect(w,-h,{w/2,w/2,0,0},ret);
popMatrix();
}
}
class Body extends Rect{
void draw(){
l = this.l;
t = this.t;
r = this.r;
b = this.b;
float w = r-l;
float h = b-t;
float dr = r -rF.r;
float ra = dr>w/8?w/8:dr<0?0:dr;
pushMatrix();
translate(l+w/2,b-h/2);
rrect(w,-h,{0,ra,0,0},ret);
popMatrix();
/*pushStyle();
noFill();
stroke(#000000);
strokeWeight(1);
rect(l,t,r-l,b-t);
popStyle();*/
}
}
class Head extends Rect{
void draw(){
l = this.l;
t = this.t;
r = this.r;
b = this.b;
float w = (r-l)*2;
float h = -(b-t)*2;
//rect(l,b,w,h);
arc(l, b, w, h, 0, HALF_PI);
}
}
class Eye extends Rect{
void draw(){
l = this.l;
t = this.t;
r = this.r;
b = this.b;
float w = (r-l);
float h = (t-b);
ellipse(l+w/2, t-h/2, w+2, h+2);
pushStyle();
fill(#FFFFFF);
ellipse(l+w/2, t-h/2, w, h);
popStyle();
}
}
class Antenna extends Rect{
void draw(){
l = this.l;
t = this.t;
r = this.r;
b = this.b;
pushStyle();
stroke(c);
strokeWeight(2);
line(l,b,r,t);
popStyle();
}
}
class Shadow extends Rect{
void draw(){
l = this.l;
t = this.t;
r = this.r;
b = this.b;
float w = (r-l);
float h = (b-t);
pushStyle();
fill(c,51);
arc(l, t+h/2, w*2, h, PI+HALF_PI,TWO_PI+HALF_PI);
popStyle();
}
}
void regen(float []v){
regen_d(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8],v[9],v[10],v[11],v[12],v[13],v[14]);
}
Android(float []v){
init();
regen(v);
}
float s ;
void init() {
if(width < height){
s = (float) (width /( D_W *2 *1.5));
}else{
s = (float) (height / (D_H * 1.8));
}
rF = new Foot();
rB = new Body();
rH = new Head();
rA = new Arm();
rE = new Eye();
rT = new Antenna();
rS = new Shadow();
}
private void regen_d(float l_p_xf, float l_p_ab, float l_p_hb,
float l_f_w,float l_f_h,
float l_b_w, float l_b_h,
float l_a_w, float l_a_h,
float l_h_w, float l_h_h,
float l_e_r,
float l_t_d,float l_t_w,float l_t_h ) {
float p_xf = l_p_xf;
float p_ab = l_p_ab;
float p_hb = l_p_hb;
float f_x = p_xf;
float f_y = 0;
float f_w = l_f_w;
float f_h = l_f_h;
rF.reBound(f_x, f_y, f_w, f_h);
float b_x = 0;
float b_y = rF.t;
float b_w = l_b_w;
float b_h = l_b_h;
rB.reBound(b_x, b_y, b_w, b_h);
float a_x = rB.r + p_ab;
float a_w = l_a_w;
float a_h = l_a_h;
float a_y = rB.t - a_h;
rA.reBound(a_x, a_y, a_w, a_h);
float h_x = 0;
float h_y = rB.t + p_hb;
float h_w = l_h_w;
float h_h = l_h_h;
rH.reBound(h_x, h_y, h_w, h_h);
float e_r = l_e_r;
float e_x = h_x + h_w/3;
float e_y = h_y + h_h/2;
float e_h = l_e_r*2;
float e_w = l_e_r*2;
rE.reBound(e_x, e_y, e_w, e_h);
float t_x = h_x+(float) (h_w* Math.cos(l_t_d*Math.PI/180));
float t_y = h_y+(float) (h_h* Math.sin(l_t_d*Math.PI/180));
float t_w = l_t_w;
float t_h = l_t_h;
rT.reBound(t_x, t_y, t_w, t_h);
float s_x = 0;
float s_w = b_w + a_w;
float s_h = s_w/3;
float s_y = f_y - s_h/2;
rS.reBound(s_x, s_y, s_w, s_h);
free =new float[] {p_xf, p_ab, p_hb, f_w, f_h, b_w, b_h, a_w, a_h, h_w, h_h, e_r, t_x, t_w,t_h};
}
static float[] rand(){
float min = 0.5f;
float max = 1.5f;
float tall = roll(D_H,min,max);
int n1= random(1,7);
int n2 = random(1,9-n1);
float lf_h = tall * n1 /10;
float lb_h = tall * n2 /10;
float lh_h = tall -lf_h-lb_h;
float lb_w = roll(D_B_W,min,max);
float lh_w = roll(D_H_W,0.2f,1.5f);
n1= random(1,7);
n2 = random(1,10-n1);
float lp_xf = lb_w * n1 /10;
float lf_w = lb_w * n2 /10;
float la_w = roll(D_A_W,0.2f,1.5f);
float la_h = roll(lf_h+lb_h,0.2f,1.0f);
float lp_ab = D_P_AB;
float lp_hb = D_P_HB;
float le_r = D_E_R;
float lt_x = random(20,80);
float lt_w = roll(D_T_W,0.5f,1.5f);
float lt_h = roll(D_T_H,0.5f,1.5f);
float []rand = new float[]{lp_xf, lp_ab, lp_hb, lf_w, lf_h, lb_w, lb_h, la_w, la_h, lh_w, lh_h,le_r,lt_x,lt_w,lt_h};
return rand;
}
static float roll(float v, float min,float max){
return v * random(min,max);
}
void draw(){
rT.draw();
rS.draw();
rF.draw();
rB.draw();
rH.draw();
rA.draw();
rE.draw();
}
}
/****************** MAIN **********************/
frame = 30;
boolean isLooping;
int r = 0x74;
int g = 0xAC;
int b = 0x23;
color c = color(#74AC23);
color bg = color(#CCCCCC);
Android android;
void setup() {
background(bg);
intial(externals.canvas.width,externals.canvas.height);
}
void intial(String hash,int w,int h){
size(300,480);
loadAvatar(hash);
noStroke();
//c = randColor();
//bg = randColor();
fill(c);
android = new Android(Android.D_V);
//android = new Android(Android.rand());
smooth();
noLoop();
isLooping = false;
frameRate(frame);
}
String getAvatarUrl(String hash,int size){
return "http://www.gravatar.com/avatar/"+hash+"?d=404&s="+size;
}
PImage avatar;
boolean loadAvatar(String hash){
int size = min(width, height);
url = getAvatarUrl(hash,width);
console.log(url);
avatar = loadImage(url);
//avatar.sourceImg.crossOrigin = "";
}
void drawAndrod(){
if(isLooping){
float [] v = new float[inc.length];
for(int i =0 ;i<inc.length;i++){
v[i] = android.free[i] + inc[i];
}
r +=rc;
g +=gc;
b +=bc;
c= color(0xff000000 | (int)r<<16 |(int)g<<8 |(int)b);
fill(c);
android.regen(v);
}
if(frameCount>=frame){
stop();
}
background(bg);
pushMatrix();
translate(width+Android.D_H *0.6,height-Android.D_H/9);
rotate(PI-PI/4);
scale(android.s ,android.s);
android.draw();
scale(-1 ,1);
android.draw();
popMatrix();
}
void draw() {
drawAndrod();
}
void stop(){
noLoop();
frameCount = 0;
isLooping = false;
}
void restart(){
loop();
isLooping=true;
}
void mouseClicked() {
if(isLooping){
stop();
}else{
reRand();
restart();
}
}
float []inc;
void reRand(){
float [] target = Android.rand();
randColor();
inc = new float[target.length];
float c = 1.0f/frame;
for(int i =0 ;i<inc.length;i++){
inc[i] = (target[i] - android.free[i])*c;
}
}
int rc,gc,bc;
color randColor(){
int rr = (int)random(0xff);
int rg = (int)random(0xff);
int rb= (int)random(0xff);
rc = (rr -r) /frame;
gc = (rg -g) /frame;
bc = (rb -b) /frame;
return color(0xff000000 | (int)rr<<16 |(int)rg<<8 |(int)rb);
}
PVector[] rrect(float w, float h, float[] r, int res) {
PVector[] ret = new PVector[res*4];
int[] cor = new int[]{-1, -1, 1, -1, 1, 1, -1, 1};
float[] ang = new float[]{PI, PI+HALF_PI, 0, HALF_PI};
float inc = HALF_PI/res;
beginShape();
for(int a=0; a<4; a++) {
int crx = cor[a*2];
int cry = cor[a*2+1];
for(int b=0; b<res; b++) {
float cag = ang[a]+inc*b;
float posx = w*.5*crx + r[a]*crx*-1;
float posy = h*.5*cry + r[a]*cry*-1;
float x = posx + cos(cag)*r[a];
float y = posy + sin(cag)*r[a];
vertex(x, y);
ret[b+res*a] = new PVector(x, y);
}
}
endShape(CLOSE);
return ret;
}