总体步骤概述

1.观察图形,总结其中的规律
2.将规律转化为代码,注意封装性
3.应用鼠标的交互性,拓展作品

一、观察图形,总结其中的规律

windows ProcessBuilder 乱码 processing code_i++

(1)形状特点:
  • 一共有7层花,7圈
  • 每一圈有12个椭圆形的花瓣
  • 随着半径的减小,椭圆的大小也在发生变化,越来越小
(2) 角度特点
  • 12个椭圆平分360°,因此每个椭圆占360°/12=30°
  • 一共7层,每单数层首个椭圆的起始角度是0,每双数层首个椭圆的起始角度是15°
(3)颜色特点

随着半径的减小,颜色RGB中的G的值逐渐增大,R的值几乎维持在252左右,G的值越大,越黄。

(4)动态特点

可以观察到,随着时间的变换,花瓣的颜色在变浅,逐渐显现出边框。因此可以判断,颜色值中的alpha值在改变。且改变的差值与半径大小成正比

二、将规律转化为代码,注意封装性

(1)第一步:绘制出最外圈的一层花瓣
  • 每一圈的椭圆构成的花瓣是以圆形排布的,因此这里确定每一个椭圆的位置时,应该使用圆的坐标计算。圆的坐标这里建议选取极坐标,因为涉及到每个椭圆还需旋转一定角度的问题。
    圆的极坐标表示为:
  • 这里我们先建立一个绘制每一个花瓣的类(即一个椭圆)
    x:椭圆绘制的中心的x坐标
    y:椭圆绘制的中心的y坐标
    w:椭圆的宽度
    h:椭圆的高度
    c:椭圆的颜色
class Circle{
  float x;
  float y;
  float w;
  float h;
  color c;
  public Circle(){
  }
  public Circle(float x,float y,float w,float h,color c ){
     this.x=x;
     this.y=y;
     this.w=w;
     this.h=h;
     this.c=c;
  }
  • 为该类添加一个旋转的成员函数(因为每一个椭圆的角度是不一致的,因此这里需要改变角度)
public void   rotateSelf(float angle1){
    pushMatrix();
    translate(x,y);
    rotate(angle1);
    translate(-x,-y);
    drawCircle();
    popMatrix();
  }
public void drawCircle(){
    fill(c);
    ellipse(x,y,w,h);
  }
  • 每一层由12个花瓣组成,因此建立一圈的话,可以看为一组,这里可以建立一个类对象数组
Circle[] circle=new Circle[12];
  • 进行对象的的初始化以及绘制
    (1)之前已经知道,每30°绘制一个椭圆,那么椭圆到底绘制多大会较好呢?有可能会绘制的太大有重合,有可能绘制得太小,又间隔太大。


    这里就需要使用数学计算了,通过使用弧长公式:
    K=nPIR/180
    因为每个椭圆对应的角度是30°,因此每一个椭圆的宽度最大应该是:30PIR180=PIR/2
for(int i=0;i<12;i++)
    {
      circle[j][i]=new Circle(100,100,120-10*j,PI*R/6.0,allcolor[j]);
      if(choose==(i+3)||choose==(i+4)||choose==i||(i+1)==choose||(i+2)==choose){
        circle[j][i].setColor(color(allcolor[j],200+5*(j+1)));
      }
      circle[j][i].setLocation(R*cos(radians(angle)),R*sin(radians(angle)));
      circle[j][i].rotateSelf(radians(angle));
      angle+=30;
    }
  • 因此就绘制出了这样的一圈花瓣
(2)绘制出7层的花瓣

因为一个for循环可以绘制出一圈圆,所以7个for循环就能画出所有层。这里我们可以通过二维数组来绘制。

  • 首先需要将之前的circle数组换为二维数组,并制定好每一层的颜色
Circle[][] circle=new Circle[7][12];
color[] allcolor={color(252,109,0),color(253,130,0),color(252,148,0),color(253,171,0),color(253,192,0),color(252,211,0),color(253,232,0)};
  • 指定单层、双层的角度,因为单双层绘制起始的椭圆的位置不一致
int angle1=0;
int angle2=15;
int angle;
  • 开始绘制
for(int j=0;j<7;j++){
     if(j%2==0)angle=angle2;
      else angle=angle1;
   for(int i=0;i<12;i++)
    {
      circle[j][i]=new Circle(100,100,120-10*j,PI*R/6.0,allcolor[j]);
      if(choose==(i+3)||choose==(i+4)||choose==i||(i+1)==choose||(i+2)==choose){
        circle[j][i].setColor(color(allcolor[j]));
      }
      circle[j][i].setLocation(R*cos(radians(angle)),R*sin(radians(angle)));
      circle[j][i].rotateSelf(radians(angle));
      angle+=30;
    }
   // R-=5*(7-j);
    if(j==6)R=200;
  }
  • 结果展示:
(3)增加动态效果(忽明忽暗)
  • 这里只需要更改椭圆的颜色中的alpha通道的值即可,可以观察到,每一层的alpha的改变程度是不一致的,外层的越暗,内层的越亮,这里我们可以把它看成一个线性的变化color(allcolor[j],200+5*(j+1)),以层数作为线性变换中的变量即可。
for(int j=0;j<7;j++){
     if(j%2==0)angle=angle2;
      else angle=angle1;
   for(int i=0;i<12;i++)
    {
      circle[j][i]=new Circle(100,100,120-10*j,PI*R/6.0,allcolor[j]);
      if(choose==(i+3)||choose==(i+4)||choose==i||(i+1)==choose||(i+2)==choose){
        circle[j][i].setColor(color(allcolor[j],200+5*(j+1)));
      }
      circle[j][i].setLocation(R*cos(radians(angle)),R*sin(radians(angle)));
      circle[j][i].rotateSelf(radians(angle));
      angle+=30;
    }
    R-=5*(7-j);
    if(j==6)R=200;
  }
  • 效果展示

三、应用鼠标的交互性,拓展作品

鼠标可以拖动椭圆,能够一层一层的生成和使花瓣消失
消失:设置花瓣的颜色为黑色即可
判断位置:为花瓣类设置一个坐标的判断函数即可

public void judgeEnter(float mousex,float mousey){
    color record=this.c;
    if(mousex>x-w+400&&mousex<x+w+400&&mousey>y-h+400&&mousey<y+h+400){
      record=this.c;
      this.c=color(0);
    }else{
      this.c=record;
    }
  }

windows ProcessBuilder 乱码 processing code_i++_02


windows ProcessBuilder 乱码 processing code_ci_03


windows ProcessBuilder 乱码 processing code_for循环_04