首页 > 未分类 > 真·代码解析《四色环》
2017
10-09

真·代码解析《四色环》

之前写的几篇代码解析太幼稚了,错误百出,不过错误是进步的基石(前提是得被招安了才行)。
今天这篇代码解析比之前更近一步,由之前的给代码给成品来解析代码进化为给成品猜代码解析代码~
废话少说,进入正题。

真·代码解析《四色环》 - 第1张  | Processing编程艺术
这篇文章中的“成品”来自于iprocessing群里一位朋友“诺仟”分享的processing课程作业,毕竟是学校老师布置的作业,整道做下来让我获益匪浅,不但考察了我之前知识掌握的程度,也考验了我知识检索能力,锻炼了我的“设计”(设计/策划出一套方案,感觉像精心策划一次暗杀行动,哈哈)能力与学习能力。

非常感谢诺仟慷慨的分享!

首先拿到题目先对目标做出分析:
1,整体由大半圆组成,两个大半圆一个在画布上方一个在画布下方,并且相切;
2,两个大半圆之间的元素、属性都相同;
3,每部分有10个同心半圆,每个半圆直径等差缩小,每个半圆颜色不一样;
4,每部分的半圆一共四种颜色,分别是黄,绿,蓝,紫;
5,四种颜色依次按顺序循环对圆进行填充;

接着,对看到的情况向解决问题方面做出设想:
1,看到情况1的时候我想到的其实是吃豆人……并没有直接想到是两个半圆,但要是当做是在画布两端的两个半圆就很好解决了,因为他们共用的直径参数是一样的;
2,还是根据1,半圆只不过是圆心在画布边缘,另一半没画的上去而已,实际上还是圆,两个圆;
3,由2得知两个圆可以同时操作处理;
4,由3得知,圆的直径是递增的(正增还是负增又是另一回事)
5,由4得出,要用到周期,三角函数和余数都可以做出周期的效果,用哪个就又是一回事了,不过余数比三角函数好用,好理解;
6,由5得出,颜色方案必须与圆一一对应。

这道题的难点我认为主要集中于颜色循环与圆的一一对应上,圆好画,颜色也好上,可是固定的颜色方案还要跟着圆一一对应就要花心思了,反正我这个初自学者是夜里打着手电翻遍三书一网(权威指南,learning processing,代码本色与iprocessing)屡次想要认怂放弃之际却又屡有小线索吊着一步步走来最终击杀目标的……
上代码:

void setup(){
size(200,200);
background(255);
smooth();
//因为是重复作业,所以要用到循环,迭代的概念/思想,
//所以要用到for语句
//设置一下w的情况,w的“行动模式”
//从200开始,也就是画布的宽度,
//十个圆,也就是200/10=20,
//每次减20
//再给w一个范围,大于等于0就行了
//w也就取200,180,160,140,120,100,80,60,40,20,0
//这虽然是十一个数,但是w取0时不画圆,因为直径为0
//直径为0的圆你看不到,因为奥卡姆剃刀原理,所以也就不存在
//这里的w是一个主干,因为我们的主干是圆
//颜色是填充在圆上的
//w是为了画圆而设计的
//关于颜色的设计方案,则是跟着圆走
//w算是圆的一个编号体系
for(int w =200;w>=0;w=w-20){
//这里开始设计圆的颜色填充方法
//我的想法是,既然是四个一循环,那就可以用到余数的概念
//因为20到200都是整20数,
//不太好设计这些数字除以某一个数并将余数控制在0到3之间
//于是就需要将w映射到1到10之中,
//1到10这些数字非常好控制余数,
//除以4就能将余数控制在0,1,2,3之中了
//但是1到4是小于等于4的,这需要用4来除以这些数,
//表达起来非常不方便
//所以我将最小数直接调整为4
//那么就是将20到200映射进4到14
//又因为关于映射运算中一些我不了解的细节,
//c并不是一个x.0的整数,并且随着这些细微差距的累计
//就算我用了四舍五入的round()函数后
//还是不能按照我的理想得出4到14的连续整数
//最后我试着把最小数4调整为5
//居然成功了……
//成功地输出了4到14的连续的10个x.0式的整数
//c也就相当于是圆的第二套编号
float c =round(map(w,20,200,5,14));
//设计一个数——i
//以此作为颜色方案的编号
//i的值等于c除以4的余数
//因为c的值是4,5,6,7,8,9,10,11,12,13,14
//所以c除以4的余数总是
//0,1,2,3,0,1,2,3,0,1,2
//至此,我们成功地设计出了填色方案的编号
//以及编号的放置/循环方案
float i =c%4;
//从这里开始,依次开始给每个编号写上对应的方案
//因为代码是依次执行的
//第一个w是200,也就是最大的圆,
//所以对应的w应该使用编号为2的填色方案
//所以要将2设置为第一个碰到的方案,
//也就是循环的第一位

//接下来要用到if语句了,
//几个“并列”的if下面是画圆的函数
//if和ellipes函数都是“并列”的
//并没有哪个包含在哪个块里面,
//都是同时包含在for这个块之中的,
//所以运行顺序是
//for(xxxxxxx)
//1号if
//2号if
//3号if
//4号if
//(哪个if成功了,就跳过“并列”的其它if,直接进入下一步)
//上下同时画出一个圆
//循环往复
//没有玄学,没有歧义
//只有逻辑,死板又直到不行的逻辑
//简单又粗暴,一点弯弯也不绕
if(i==2){
//最大圆的颜色是黄色,
//所以填充黄色
fill(255,255,0);
}
//第二个w是180,对应的填色方案是1
//也就是说编号为1的填色方案应该第二个碰到
//也就是说编号为1的填色方案在循环的第二位
if(i==1){
//写明该方案如何填色
fill(0,255,0);
}
//第三个w是160,对应的填色方案是0
//也就是说编号为0的填色方案应该是第三个碰到
//也就是说编号为0的填色方案在循环的第三位
if(i==0){
//写明0号方案该如何执行
fill(0,0,255);
}
//第四个w是140,对应的填色方案是3
//也就是说编号为3的填色方案应该是第三个碰到
//也就是说编号为3的填色方案在循环的第四位
if(i==3){
//写明该方案如何填色
fill(255,0,255);
//接下来的120,100,80,60,40,20
//又像之前讲解的一样一一对应地“刷”下来
}
在最后,因为填色方案已给明,
//交代一下,根据w画圆就行了
//需要再提一下的是
//processing与自然绘画逻辑不同
//我们画圆是
//画出圆
//给圆填色
//而processing是
//声明以下出现的图形都填某种颜色
//给出/画出上一行中提到的“以下”图形
ellipse(100,0,w,w);
ellipse(100,200,w,w);
}
}

代码一共23行,
诺仟同学当时给出的答案也是23行,
算是某种程度上的不谋而合……
但是她的解法与我的有些区别
她并没有用到map()函数
而是缩小w的值,并且用乘以200,180到20的一个公约数来还原
这样设计就使得w不用映射也能得出一系列简单的数来进行余数运算
还有一点不同的是,她在填色上直接用的颜色编号
比我少写好多字……
实际上她的代码还能再缩两行,
void draw和最后的一个}可以省下来
总结下来就是一句话,如果确认了当前水平能击杀的,那就真的是能击杀的。

然后,
计算机诚不欺我!编程语言诚不欺我!逻辑语言诚不欺我!



最后编辑:
作者:DurianBomb
这个作者貌似有点懒,什么都没有留下。

真·代码解析《四色环》》有 2 条评论

  1. becky__ 说:

    我试着写了一下是用了20行

留下一个回复

你的email不会被公开。