曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

这篇具有很好参考价值的文章主要介绍了曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/

译者:池中物王二狗(sheldon)

源码:github: https://github.com/willian12345/coding-curves

第十章 螺旋(SPIRALS)

曲线艺术编程系列第 10 章

来聊聊螺旋线。

螺旋非常像圆,它是一组点到定圆中心点的距离关系。与圆不同的是,圆的点与中心点距离固定不变,而螺旋上的点与中心点距离是变化的。给定点与中心点的距离通常是由一个基于两点之间的角度计算得到。所以你需要有函数传入角度返回半径。然后你可以通过半径与角度找到那个角度上对应的点。有很多不同的螺旋公式,会得到不同形态的螺旋。让我们从最基础的一个开始。

注:圆有时候也被称为“退化”的旋转。“退化”这词在这里没有贬义,只是说圆遵循螺旋的“规则”但又不是通常我们想象中的螺旋。就像一个三角形其中某一边的长度为 0。所有三角形数学计算通常都能正常工作,但在我们眼中它却成了一条线。

阿基米德螺旋

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

如你所见,每个圆的半径都会定量增加。下面是这个螺旋线的公式:

r = a * t

此处,t 是弧度 a 是某个常量,上图中 a 设为 5。 两者相乘的结果即是这个 t 角度上的半径值。如果将 6 增加到 10,我们会得到如下 :

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

现在如你看到的这样,常量 a 决定了螺旋内每个圆之间的间距。在这个例子中,螺旋都旋到 canvas 边界外了。

当我们绘制螺旋时,我们首先需要决定绘制多少个圈。要绕多少圈?如果 t 从 0 到 2 * PI,我们得到的是一个圈:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

你可以看到这个螺旋有一个圈,螺旋曲线从中心开始向外扩展。三个圈表示 t 从 0 到 2 * PI * 3。

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

有了上面这些,我们可以将它们合在一起创建一个螺旋线的调式器(playground),像这样:

width = 800
height = 800
canvas(width, height)
translate(width / 2, height / 2)
 
cycles = 10
res = 0.01
 
for (t = res; t < 2 * PI * cycles; t += res) {
  r = archimedean(5, t)
  x = cos(t) * r
  y = sin(t) * r
  lineTo(x, y)
}
stroke()
 
function archimedean(a, t) {
  r = a * t
  return r
}

比如我们希望有 10 个圈, 循环结束点就是 2 * PI * cycles。调用 archimedean 螺旋函数,传入 5 作为它的常量, t 作为弧度。它会返回给我们一个半径值,我们可以用它和弧度计算出对应点的 x, y 坐标并用线连接。

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

我使用的绘图 api , 角度正向增加是顺时针方向。所以这个螺旋从中心顺时针绕出来。这可能与你正在使用的编程平台内表现有所不同。这取决于你使用的绘图 api 如何处理角度方向。为了翻转旋转方向,有几种方式:

A. 用 scale 翻转 canvas

scale(1, -1)

B. 改变代码创建点的方式,使其中一个轴为负 例如:

x = cos(t) * r
y = -sin(t) * r

C. 将循环的方向变反

for (t = -res; t > -2 * PI * cycles; t -= res) {

任意一种方式都可以让你的螺旋方向改变。

还有最后一件事...

代码中值得注意的一点是循环起始点是 res 而不是 0

for (t = res; t < 2 * PI * cycles; t += res) {

想知道为我为啥这么做,我们需要从下一种螺旋线寻找答案。

双曲线螺旋 Hyperbolic Spiral

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

这个螺旋与第一个螺旋看起来非常不同。上个螺旋内每个圈是等距的。你可能会说每个圈之间的距离都增长了,还是等等先别下结论。

下面这个函数是这个螺旋准备的:

function hyperbolic(a, t) {
  r = a / t
  return r
}

也没有特别大的不同。我们用除代替了乘。上图我传入了 1000 。如果我将值降到 10, 我们会得到一个很小的螺旋线像这样:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

这就很明显了 for 循环以 res 开始而不是 0, 如果是 0,那么就会出现除数为 0 的这种情况,这会导致某些问题。也许会崩溃,或者半径为 NaN (not a number) 值, 这没什么用。所以我们将起始值设为非 0。

另一个值得注意的事是螺旋线的旋转方向。上图我画了 20 个圈。如果降为 5(a 变回 1000),将得到:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

你现在可能看到随着 t 值增长螺旋变的很大但,但增长的速度慢小了。当有 100 个圈,螺旋中心位置开始有些堵了。

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

就如我之前所说,咋一看每个圈半径都在增长,但你现在可以观察到实际上是开始时很大,但是圈与圈之间的半径值逐渐变小了。

费马螺线

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

这种螺旋线很漂亮。这是公式:

function fermat(a, t)  {
    r = a * pow(t, 0.5)
    return r
}

这里我们将 a 乘以 t 的 0.5 平方。假定你的编程语言内置了 pow 函数计算第一个参数的第二个参数次幂。根据你使用的编程语言,它可能是这样:

r = a * (t^0.5)

or

或这样:

r = a * (t**0.5)

上一张图 a 设为了20 绘制了 20 圈。 绘制 10 圈 结果如下:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

可以看到螺旋线是从内向外绘制的。 一开始圈与圈之间的间距比较大,但越往外面圈的间距越来越小,还超出边界了

圈数改回 20 个圈 a 设为 40:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

我们能看到间距有所增加。

100 个圈 a 设为 15。

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

最终,每圈之间已很难有间距。而我们得到了一些有趣的摩尔纹图案

连锁螺线 Lituus Spiral

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

它看起来像双曲螺线,但公式却更接近于费马螺线:

function fermat(a, t)  {
    r = a * pow(t, -0.5)
    return r
}

我们公需要将指数中的 0.5 改为 -0.5。上图螺旋线绘制了 20 个圈 a 的值为 500。 下面是 10 个圈

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

你可以看到这是另一种向内绘制的螺旋线。 改回 20 圈, a 设为 50,得到:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

词 “Lituus” 原意是弯曲的杖,弯曲的魔法棒或角。上图很好的解析了它名字的由来。

将 a 升到 1000, 可以得到:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

可以这样讲,a 值越低,螺旋吞噬进中心越快。

还有很多类型的螺旋线,来,继续!

对数螺旋 Logarithmic Spiral

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

它有点像反费马螺旋。一开始间隔挺小,越往外越大。公式:

function logarithmic(a, k, t)  {
    r = a * exp(k * t)
    return r
}

公式看起来比之前遇到过的要复杂一点。t 前有两个参数。我们先从 exp 函数开始学习。

我们实际上在谐振波图(Harmonographs) 这一章见过它. 回顾一下,有一个数学常数 e ,也称欧拉数。它的值大概是 2.71828。 当我们在与对数打交道时,常将 e 乘方。所以很多数学程序库会直接提供一个函数, 常被命名为 exp。 举个具体的例子,在 javascript 中,有常用 e, Math.E。为了计算 e 的 2 次幂,就得像下面这样做:

Math.pow(math.E, 2)

但其实已经有一个叫 exp 的函数了,你可以直接用:

Math.exp(2)

代码中的公式也得改成,

r = a * exp(k * t)

我们用 a 乘以 e 的 k * t 次幂。上面的图,我得将 a 设成 0.5 且 将 k 设为 0.05。

如果将 a 变为 1,我们将得到一个相当大的螺旋线,虽然它们看起来很像。

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

a 设为 0.24 后:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

还是挺像的,但更小一点儿了。

将 a 重置为 0.5 并且将 k 升到 0.1

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

你可以看到扩张的更快了。将 k 设为 0.04 它对结果的影响远超我的预期

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

黄金螺旋(Golden spiral)

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

这类螺旋增长率叫“黄金比例”,大概接近 1.618。它的公式是:

function golden(t) {
    r = pow(PHI, 2 * t / PI)
    return r
}

首先,这个函数除了 t 之外没有其它参数。 PHI 黄金比例值是硬编码在函数内的。很多数学程序库都有黄金比例这个内建常量。如果你没有,将这近似的设置为:

PHI = 1.61803

或者你想更精确一点,你可以像下面这样写得到精确值:

PHI = (1 + sqrt(5) ) / 2

然后放在某个地方按需引用即可。

你很可能已经见过这种螺旋图了:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

By Romain – Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=114415511

这实际是一个斐波那契螺旋。方块大小是下两个方块之和且每个方块内的曲线是一个角为中心 90 度生成弧线。它不是精确的黄金螺旋,但很接近了。

还有更多

仔细阅读这个螺旋线列表,也许你能找到其它更有趣的

https://en.wikipedia.org/wiki/List_of_spirals

还有:

https://mathworld.wolfram.com/topics/Spirals.html

螺旋角(Spirangles)

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

在写这一章的时候我偶然发现了这个词 (Spirangles)。本质上它是由直线线段组成的螺旋。通过改变每个线段的角度,你可以将它们组成不同的形状。

在已有的基础上实现它非常容易。上面中有个例子使用的是 archimedean 函数,a 为 3,并且 cycles 为 20。 窍门是减低分辨率 res 上图的效果我是将 res 设为了发下值:

res = PI * 2 / 3

Now on each step of the for loop, t will increase by one-third of a circle. Here are some others, dividing by 4 and 5.

现在,循环中每一步,t 会增加 1/3 个圆。 以下是其它, 除 4 和 除 5 的效果:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

窍门你已经知道了。你可能想在其它方法上试试。其中一些通过这样修改后变的让人相当满意。

葵花螺旋(Sunflowers)

若是没有讨论葵花螺旋,那么螺旋这一篇就不算完整。试试用葵花,斐波那契与螺旋的组合搜索,你能得到巨量的阅读材料与漂亮图片。我的意思是,除了绘制葵花螺旋这类有趣的螺旋线外,其它的螺旋我就让你自己去探索了。黄金比例在这个图中是天生的,图是这样:

曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)

你可以看到不止一条螺旋,有许多螺旋以不同角度进进出出。我常用下面的代码实现(还是以伪代码展示):

width = 800
height = 800
canvas(width, height)
translate(width / 2, height / 2)
 
count = 1000
for (i = 0; i < count; i++) {
  percent = i / count
  size = 14.0 * percent
  r = 380.0 * percent
  t = i * PI * 2 * PHI
  x = cos(t) * r
  y = sin(t) * r
  circle(x, y, size)
  fill()
}

我们用变量 count 代表想要绘制多少“葵花籽”。这里 count 设为了 1000.

然后我们循环 用 i / count 得到一个百分比值。

变量 size 是每颗“种子”的半径。当 i 越接近 count 时,percent 的值会越接近 1,因此 size 的值也会越接近最大值 14。

同样 r 用于表示种子分布的半径。它最高值是 380, 仅比 canvas 宽度的一半小一点点。

我们用 t = i * PI * 2 * PHI 计算出 t , 它就是神奇的葵花斐波那契公式。说真的,你想知道更多,那就认真看一下。有了角度和半径,我们就可以得到 x 和 y 坐标,然后根据种子自己的大小绘制种子了。

到目前为止我想说的螺旋线就这么多了。下回见!

本章 Javascript 源码 https://github.com/willian12345/coding-curves/blob/main/examples/ch10


博客园: http://cnblogs.com/willian/
github: https://github.com/willian12345/文章来源地址https://www.toymoban.com/news/detail-482047.html

到了这里,关于曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 曲线艺术编程 coding curves 第六章 平托图 (Pintographs)

    原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) blog: http://cnblogs.com/willian/ 源码:github: https://github.com/willian12345/coding-curves 曲线艺术编程系列第 6 章 另一个可用于模拟绘制复杂曲线的物理装置叫平托图(Pintograph), 事实上我真的自己弄了一个。

    2024年02月08日
    浏览(44)
  • 曲线艺术编程 coding curves 第七章 抛物线(Parabolas)

    原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) blog: http://cnblogs.com/willian/ 源码:github: https://github.com/willian12345/coding-curves 曲线艺术编程系列第7章 我承认这一章脑暴时,再三考虑过是否要将抛物线包含进来。此篇覆盖的抛物线比起之前三章

    2024年02月08日
    浏览(43)
  • 曲线艺术编程 coding curves 第五章 谐波图形(谐振图形) HARMONOGRAPHS

    原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) blog: http://cnblogs.com/willian/ 源码:github: https://github.com/willian12345/coding-curves 曲线艺术编程系列第 5 章 这一篇幅建立在对第四章利萨茹曲线的讨论之上。事实上谐波图形并不是一类曲线,它是一

    2024年02月08日
    浏览(38)
  • 曲线艺术编程 coding curves 第三章 弧,圆,椭圆(ARCS, CIRCLES, ELLIPSES)

    原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) blog: http://cnblogs.com/willian/ 源码:github: https://github.com/willian12345/coding-curves 曲线艺术编程系列第三章 这一篇中我们将关注如何绘制圆弧,圆和椭圆。(结束前再聊聊正切相关的) 很可能你使用

    2024年02月07日
    浏览(47)
  • Bezier Curve 贝塞尔曲线 - 在Unity中实现路径编辑

    贝塞尔曲线( Bezier Curve ),又称贝兹曲线或贝济埃曲线,是计算机图形学中相当重要的参数曲线,在我们常用的软件如 Photo Shop 中就有贝塞尔曲线工具,本文简单介绍贝塞尔曲线在Unity中的实现与应用。 给顶点P 0 、P 1 ,只是一条两点之间的直线,公式如下: B(t) = P 0 + (P

    2024年01月23日
    浏览(43)
  • 贝塞尔曲线(Bezier Curve)原理、公式推导及matlab代码实现

    目录 参考链接 定义 直观理解  公式推导 一次贝塞尔曲线(线性公式) 二次贝塞尔曲线(二次方公式)  三次贝塞尔曲线(三次方公式) n次贝塞尔曲线(一般参数公式) 代码实现 贝塞尔曲线(Bezier Curve)原理及公式推导_bezier曲线-CSDN博客 贝塞尔曲线(Bezier Curve)原理、公

    2024年01月20日
    浏览(47)
  • 自动驾驶——基于五次多项式螺旋线方程的换道曲线规划

    1.BackGround 已知:换道初始纵坐标y0(横向距离),换道初始航向角tan0,换道时间t,换道结束纵坐标yf,换道结束航向角tanf,车速VehSpd,曲线中点曲率q且曲率变化率为0。求解期望的规划曲线。 2.Algorithm 3.Reference 自动驾驶——ADAS车道线方程推导 基于多项式采样的换道路径规划

    2024年02月08日
    浏览(63)
  • 递归的递归之书:第十章到第十四章

    原文:Chapter 10 - File Finder 译者:飞龙 协议:CC BY-NC-SA 4.0 在本章中,你将编写自己的递归程序,根据自定义需求搜索文件。你的计算机已经有一些文件搜索命令和应用程序,但通常它们只能根据部分文件名检索文件。如果你需要进行奇特、高度特定的搜索怎么办?例如,如果

    2024年01月20日
    浏览(44)
  • 第十章 面向对象编程(高级)

    定义语法: 访问修饰符        static        数据类型        变量名; 类变量也叫 静态变量/静态属性 ,是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。 (

    2024年02月06日
    浏览(57)
  • 《TCP IP网络编程》第十章

    并发服务端的实现方法:         通过改进服务端,使其同时向所有发起请求的客户端提供服务,以提高平均满意度。而且,网络程序中数据通信时间比 CPU 运算时间占比更大,因此,向多个客户端提供服务是一种有效的利用 CPU 的方式。接下来讨论同时向多个客户端提供

    2024年02月15日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包