第十四章 其它曲线(Miscellaneous Curves)
原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/
译者:池中物王二狗(sheldon)
曲线艺术编程系列 第十四章
这是系列文章规划的最后一章。如果后面发现其它有趣的曲线类型可能加在这一章。我原计划清单里有几个主题没放出来,当然也不排除某天我改主意了。未来额外的内容也可能另起一章加到目录索引中。
在“最后”一篇, 我想我会讲一些随机曲线,这些曲线不值得单独开一章来讲。还有,我觉得把我从找到公式到编码的过程完整过一遍会很不错。
大麻曲线
Weisstein, Eric W "大麻曲线" 来源于网站 https://mathworld.wolfram.com/CannabisCurve.html
Wolfram Mathworld 是一个很好的发掘有趣公式的地方,顺便说一句,如果你想发掘更多 2d 曲线,那么在平面曲线(Plane Curve)这一章节可以深入找找。网站内容很全,还有其它曲线类型可探索。
为什么选择大麻曲线?。我只是觉得它很酷(译者注:本人在此申明我与赌毒不共戴天),仅仅用简单的相关地数学公式就可以画出如此复杂的东西。
下面是对应的数学公式:
好的,公式有点儿长,但它只是乘法,加法还有一些正弦和余弦计算。我们可以的。
它定义了一条极坐标曲线,这意味着相比于 x, y 的值,我们更关心角度与半径。我们有个函数 r(θ)
, θ
是希腊字母,theta。它通常代表角度。当然我们也能猜到 r 代表半径。所以我们需要一个函数传入角度得到对应的半径。
有了角度和半径,我们很容易计算出用于绘制线段的 x,y 点。组织代码后应该像下面在这样:
for (t = 0; t < 2 * PI; t += 0.01) {
radius = r(t)
x = cos(t) * radius
y = sin(t) * radius
lineTo(x, y)
}
stroke()
我们通过 t 计算得到半径,然后再通过半径和 t 计算得到下一个绘制线条的坐标点。
不过事实上来讲,r(θ) 除了在这个循环内不会在其它任何地方使用,我就直接硬编码了。
此处唯一额外要说明的就是需要传入参数 radius 用 radius 乘以公式。还需要用 x, y 让曲线居于中心点,所以我们也把它作为参数传递(xc 与 yc 代表 x 和 y 中点)。
(译者注:这里原作都在 r(t) 计算时用字母小 a 指代除公式之外的部分, 我觉得更难理解更麻烦,小 a 在英语中随处可见,又不在伪代码中明确标出,所以我决定去掉。直接用中文表达出作者原本的意图)
以下面代码作为起点:
function cannabis(xc, yc, radius) {
for (t = 0; t < 2 * PI; t += 0.01) {
r = radius * ... // that whole formula. we'll get to it.
x = cos(t) * r
y = sin(t) * r
lineTo(xc + x, yc + y)
}
closePath()
}
现在,我们在上面基础上进行编码。相当的简单,我们只需代入公式。分数部分我们使用 0.1 代替 1/10, 0.9 代替 9/10。开始吧!
function cannabis(xc, yc, radius) {
for (t = 0; t < 2 * PI; t += 0.01) {
r = radius * (1 + 0.9 * cos(8 * t)) * (1 + 0.1 * cos(24 * t)) * (0.9 + 0.1 * cos(200 * t)) * (1 + sin(t))
x = cos(t) * r
y = sin(t) * r
lineTo(xc + x, yc + y)
}
closePath()
}
现在,像下面代码这样看看:
canvas(600, 600)
cannabis(300, 300, 140)
stroke()
That gives me this image:
这会得到如下图:
Ah, 好的,有点儿东西。
首先,此公式使用笛卡尔坐标系,而我用的是上下相反的屏幕坐标系。所以我需要把 y 轴翻转。问题不大。
接着,中心点是所有“叶子”连接点。所以在翻转后,我可以将中心点设置在 canvas 靠近底部的位置。
最后,我猜 140 会是一个不错的半径值,它会将绘制出的图形限制在 600X600 大小的 canvas 内。事实上,我期望的是把图形限制在 canvas 大小的一半。但实际上大的叶子超出一部分也不影响。我们可以在代码中修复它,比如将半径乘以某些小数让大的叶子半径降下来。我就不做这部分限制了,我假装自己只会传合适的值,相关限制代码你自己可以搞定的。
function cannabis(xc, yc, radius) {
for (t = 0; t < 2 * PI; t += 0.01) {
r = radius * (1 + 0.9 * cos(8 * t)) * (1 + 0.1 * cos(24 * t)) * (0.9 + 0.1 * cos(200 * t)) * (1 + sin(t))
x = cos(t) * r
y = sin(t) * r
lineTo(xc + x, yc - y)
}
closePath()
}
我所做的只是将 lineTo 这一行用yc + y
代替了 yc - y
。
在调用函数时参数也调整了一下(经过试错后得出还不错的参数值)
canvas(600, 600)
cannabis(300, 520, 120)
stroke()
结果还阔以!
提醒一下。我经过仔细考虑调整了 canvas 的大小,这样 yc 参数值可以设置到 420。 你调不调的隨你
标签:...,cos,公式,yc,曲线,coding,Miscellaneous,xc,sin From: https://www.cnblogs.com/willian/p/17528280.html