总体步骤概述
1.观察图形,总结其中的规律
2.将规律转化为代码,注意封装性
3.应用鼠标的交互性,拓展作品
一、观察图形,总结其中的规律
(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;
}
}