我要做什么?

Sutcliffe Pentagons!一个奇异的分形怪咖——

绘制一个普通的五边形,然后找出其五边中每一边的中点并过这些点绘制垂直于此边的线段,而这些线段的末端则连接生成另一个五边形。我打个草图:

在这样做的同时,该形状的其余部分也最终被细分为更多的五边形。这意味着在每个五边形内有六个副五边形。在其中的每一个中,又有六个子五边形向下重复……

接着,怪咖出现了。


###我怎么做的?
Do you find yourself overly thrilled by the mathematics of this?

打开你的草图—— Processing, 开工吧!!!
####Step 1: Drawing a pentagon using rotation
画一个普通的五边形,你会怎么做?

我选用的是一种较通用的方式:

围绕屏幕中心旋转360度,并以特定角度推算顶点。例如,如果每72度绘制一个点,那我们就会得到一个五角形。

// 根类
class Root {PVector[] pointArr;  // 顶点的数组Branch rootBranch;Root() {pointArr = new PVector[sideNum]; // 五边形时,sideNum=5int count = 0;for (float i = 0; i<360; i+=360/sideNum) {float x = width/2 + (400 * cos(radians(i)));float y = height/2 + (400 * sin(radians(i)));if (count < sideNum) {  // 保证数组长度pointArr[count] = new PVector(x, y);}count++;}rootBranch = new Branch(0, pointArr);}void display() {stroke(strokeHue, 70, 100, 100);rootBranch.display();}
}

####Step 2: Functions to calculate the midpoints of a set of vertices
根发芽长成了枝丫。

我们需要一个枝丫类。枝丫从根那里得到生长的消息,它开始猥琐发育了。

在这里,我们会接收五边形每个顶点的坐标,用以求得中点。

// 枝丫类
class Branch {int level, num;PVector[] outerPoints = {};PVector[] midPoints = {};PVector[] projPoints = {};Branch[] myBranches = {};Branch(int lev, PVector[] points) {level = lev;outerPoints = points;midPoints = calcMidPoints();projPoints = calcStrutPoints();if ((level+1) < maxLevels) {Branch childBranch = new Branch(level+1, projPoints);myBranches = (Branch[])append(myBranches, childBranch);for (int k = 0; k < outerPoints.length; k++) {int nextk = k-1;if (nextk < 0) { nextk += outerPoints.length;}PVector[] newPoints = { projPoints[k], midPoints[k], outerPoints[k], midPoints[nextk], projPoints[nextk] };childBranch = new Branch(level+1, newPoints);myBranches = (Branch[])append(myBranches, childBranch);}}}// 得到每边中点的数组PVector[] calcMidPoints() {PVector[] mpArray = new PVector[outerPoints.length];for (int i = 0; i < outerPoints.length; i++) {int nexti = (i+1)%outerPoints.length;PVector thisMP = calcMidPoint(outerPoints[i], outerPoints[nexti]);mpArray[i] = thisMP;}return mpArray;}// 计算每边的中点PVector calcMidPoint(PVector end1, PVector end2) {return new PVector((end1.x + end2.x)/2, (end1.y + end2.y)/2);}void display() {strokeWeight(5-level);// 绘制外界形状for (int i = 0; i < outerPoints.length; i++) {        //int nexti = i+1;//if (nexti == outerPoints.length) {  // 首尾相连//  nexti = 0;//}int nexti = (i+1)%outerPoints.length;  // 首尾相连// 连接相邻两个点line(outerPoints[i].x, outerPoints[i].y, outerPoints[nexti].x, outerPoints[nexti].y);}// 绘制并连接中点与对应的枝点//for (int j = 0; j < midPoints.length; j++) {//line(midPoints[j].x, midPoints[j].y, projPoints[j].x, projPoints[j].y);//ellipse(midPoints[j].x, midPoints[j].y, 15, 15);//ellipse(projPoints[j].x, projPoints[j].y, 15, 15);//}// 绘制子枝for (int k = 0; k < myBranches.length; k++) {myBranches[k].display();}}
}

####Step 3: Functions to extend the midpoints toward the opposite points
毫无疑问,我们必须给定枝丫能够延伸的长度。

这时候,我定义了一个全局变量—— strutFactor 来指定希望的枝丫跨度的比例:

float strutFactor=0.2;  // 生长常数

你需要的是从中点延伸出来支柱末端的坐标集。可能你会想到利用其相对于侧顶点的角度来完成这件事。我觉得我们可以改为使用中点相对的顶点来定位。

我们将下面的两个方法加入到 Branch 类(枝丫类)。

 // 得到每个中点对应的枝点的数组PVector[] calcStrutPoints() {PVector[] strutArray = new PVector[midPoints.length];for (int i=0; i<midPoints.length; i++) {int nexti = (i+3)%midPoints.length;  // 每一边中点相对的顶点PVector thisSP = calcProjPoint(midPoints[i], outerPoints[nexti]);strutArray[i] = thisSP;}return strutArray;}// 计算中点对应的枝点PVector calcProjPoint(PVector mp, PVector op) {float px, py;px = mp.x + (op.x - mp.x) * strutFactor;py = mp.y + (op.y - mp.y) * strutFactor;return new PVector(px, py);}

为了运行方便,真正起到递归作用的代码,我早已加入到 Branch 类。

if ((level+1) < maxLevels) {Branch childBranch = new Branch(level+1, projPoints);myBranches = (Branch[])append(myBranches, childBranch);for (int k = 0; k < outerPoints.length; k++) {int nextk = k-1;if (nextk < 0) { nextk += outerPoints.length;}PVector[] newPoints = { projPoints[k], midPoints[k], outerPoints[k], midPoints[nextk], projPoints[nextk] };childBranch = new Branch(level+1, newPoints);myBranches = (Branch[])append(myBranches, childBranch);}}

根生枝,枝生根。

####Step 4: Varying the strut length of a Sutcliffe Pentagon
主标签实现了图形的绘制与变幻。strutFactor 的值范围在 - 0.5~1.0。

int sideNum = 5;  // 边数
float strutFactor=0.2;  // 生长常数
int maxLevels = 5;
float strutNoise;
Root pentagon;void setup() {fullScreen();smooth();strutNoise = random(10);pentagon = new Root();
}void draw() {background(255);strutNoise += 0.01;strutFactor = ((noise(strutNoise) * 3) - 1)/2;pentagon.display();
}


###我学到了什么?
不是所有现实事物都受益于某种结构化的规则;有一点混沌漂移才会更好。如果你有一种允许这种自由的工作方式,能够通过灵感把一种想法变成另一种想法,那么你将不可避免地踏足一些更加有趣的领域。

Recursive fractal constructions are at their root an idea stolen from natural organization. Despite how it may look when viewed through a screen, we don’t live in a digital world. Our reality is stubbornly analog: it doesn’t fit into distinctly encodable states. It’s an intricate, gnarly, and indefinite place. If we want to use digital tools to create art, which somehow has to reflect our crazy, chaotic existence, we need to allow imperfection and unpredictability into the equation. But, as I hope I’ve shown, there is room for the organic within the mechanical, and programming isn’t just about efficiency and order. Our computing machines, which may only be capable of producing poor imitations of life, are tapping a computational universality that the natural world shares.

####Last…
附上一张【Sutcliffe Pentagons】壁纸。

####相关资源:

  • 学习文献
  • 源代码下载
  • 参考博客

【Sutcliffe Pentagons】奇幻派的漂流相关推荐

  1. 《少年派的奇幻漂流》观后感

    你从派的嘴里看到了什么?宇宙.自然的神奇力量?或是创造万物的造物主代替罪恶的人类受苦?亦或是人赖以生存的信仰.目标?我不清楚,但有一点可以肯定,派从那个神话故事中女人的嘴中看到了上帝.     派的父 ...

  2. 贾扬清演讲实录:一个AI开发者的奇幻漂流

    简介:2021阿里灵杰AI工程化峰会,贾扬清深度解读阿里灵杰大数据和AI一体化平台. 演讲人:贾扬清 演讲主题:一个AI开发者的奇幻漂流 活动:2021阿里灵杰AI工程化峰会 对于绝大多数人来说,这一 ...

  3. 从南极到你家,易开得,一支“中国芯”的奇幻漂流

    2023年的AWE,精彩程度比我想象中还要夸张! 一方面是热度空前,现场人头攒动,有一家老中幼三代一起来观展的,有经销商.客户来问价采购的,还有行业媒体举着单反.手机.摄像机激情拍照的,让我们正经见识 ...

  4. 贾扬清演讲实录:一个AI开发者的奇幻漂流丨2021阿里灵杰AI工程化峰会

    演讲人:贾扬清 演讲主题:一个AI开发者的奇幻漂流 活动:2021阿里灵杰AI工程化峰会(2012年12月3日) 对于绝大多数人来说,这一波AI浪潮兴许是从深度学习开始的. 2011年谷歌发表的一篇文 ...

  5. 英语影视台词---一、少年派的奇幻漂流

    英语影视台词---一.少年派的奇幻漂流 一.总结 一句话总结:Life of Pi 1.如果我们在人生中体验的每一次转变都让我们在生活中走得更远,那么,我们就真正的体验到了生活想让我们体验的东西.? ...

  6. 中国版鲁滨逊:潘濂的奇幻漂流《一个人不能失去在生活中挣扎的能力》

    潘濂(1918.3.8-1991.1.4)是一名中国水手,他曾孤身一人在南大西洋上漂浮了133天,靠捕鱼.捉鸟和雨水为生.可以说是现实版的少年派,至今仍保持着无人能打破的救生木筏维生纪录. 潘濂在英国 ...

  7. 【阿里巴巴集团副总裁贾扬清——一个AI开发者的奇幻漂流】

    阿里巴巴集团副总裁.阿里云智能计算平台事业部负责人.达摩院 AI 平台负责人-贾扬清,以AI老兵的视角分享历经多次行业起伏的观察,以及对云原生AI时代的趋势思考.

  8. 智能体的奇幻漂流之“成都折叠”篇

    不久之前,我们曾经介绍分析过华为发布"智能体"技术参考架构,对于产业智能革命的鼎新作用.其中咱们一起聊过深圳的"鹏城智能体"有种种智能价值.对此,有读者留言询问 ...

  9. 「BTC之城」的奇幻漂流

    "这里有四百五十家商店和三千多家公司,"Mermal指着下面的小型经济体解释道."但如果没有文化,这一切都不值一提.没有文化,艺术和创新,你就拥有一个没有灵魂的城市.&q ...

  10. 抖音的奇幻漂流:为什么TikTok让用户如此着迷?

    作者:读芯术 来源:读芯术 TikTok正像风暴一样席卷全球.据Sensor Tower的数据显示,这一短视频App在苹果应用商店和谷歌Play商店上的全球下载量已经超过了20亿.它背后究竟有什么魔力 ...

最新文章

  1. 把PPT做漂亮点真的有用!图表美观能增加可信度!作者:还会影响论文引用和通过率...
  2. R语言包_Matrix
  3. 简书mysql配置_MySQL安装配置
  4. VTK:vtkBandedPolyDataContourFilter用法实战
  5. mysql insert 失败_mysql insert语句出错
  6. Linux 中的文件压缩与解压
  7. lisp 设计盘形齿轮铣刀_机械设计基础——周转轮系传动比的计算
  8. html中文本框改变事件,JavaScript onchange 事件:表单文本域或选择域发生改变
  9. Spring JPA 使用@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy 自动生成时间和修改者...
  10. 智能寻迹(循迹)小车项目思路 + 代码
  11. ARP病毒攻击技术分析与防御
  12. Vue之使用Coreui框架实现table中的checkbox多选功能
  13. var_threshold
  14. Red5 流媒体技术(初级了解)
  15. 根据程序流程图化程序流图_程序流程图有什么用?简单实用的流程图模板大全...
  16. 靶机渗透练习99-hacksudo:FOG
  17. 添加企业微信免验证设置
  18. 加速度随机游走_怎么才能形象的说明IMU的bias随机游走?
  19. 数据仓库、数据湖、数据平台和数据中台的概念和区别
  20. 腾讯题目——求磁头平均寻道长度

热门文章

  1. MaxCompute创建TableStore外表
  2. 很多人不理解这个参数的 nl,nh:ESC * m nL nH d1... dk
  3. 微软成功收购雅虎五大理由:可抗衡谷歌
  4. 666: 神奇的 SQL 之别样的写法 → 行行比较
  5. GStreamer基础教程之GStreamer工具
  6. 二、 分式化简(LCP2)
  7. php输出熊猫图案,熊猫特殊符号
  8. android 11.0 12.0Camera2 去掉后置摄像头 仅支持前置摄像头功能
  9. AboutCG的优惠卷如何使用
  10. pagefile文件大小设置