曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

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

第九章 旋轮曲线(ROULETTE CURVES)

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

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

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

曲线艺术编程系列第 9 章

一开始我本章标题我打算使用“次摆线与摆线(旋轮线)”。我想它们是两种不同类型的曲线,虽然有点儿联系。但随着了解的深入,我有点儿凌乱了。事实上摆线是一类非常特别的次摆线。我会原谅我自己的。这是维基百科上它们的定义:

在几何上,次摆线(trochoid 原自古希腊语 trochos ‘wheel’)是一个圆延一条直线滚动一圈形成的旋转曲线。

在几何上, 摆线追踪在圆上的一个点,圆延直线滚动后形成的曲线。

它们不仅不是两个不同的东西,从描述上看它们几乎是同一个东西。细节决定成败。让我们开始探索吧。

有三种不同的次摆线:

  • 普通次摆线(也称摆线)
  • Prolate trochoids 长幅摆线
  • Curtate trochoids 短幅摆线

除此之外,还有一些相关的曲线,大概覆盖以下几种:

Epitrochoids 长短辐外摆线
Hypotrochoids 长短辐内摆线
Epicycloids 外摆线
Hypocycloids 内摆线
Involutes 渐伸线

它们组合在一起就是旋轮曲线家族了。在这章除 Involutes 渐伸线外其它都将涉及到。

讲了了大堆有的没的,先从次摆线开始,让我们一一把它们搞清楚。

Trochoids 次摆线

就像上面描述的,一条次摆线就是一个圆在直线上滚动形成的旋转曲线。在编码之前先把它可视化看看:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果我们追踪圆周上的那个黑点...

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

... 新的曲线就是次摆线。事实上由于是绘制点依赖于圆周,所以也称为普通摆线或圆滚线。

如果将圆周上的点延伸超过圆周,那么我们就得到长幅次摆线(Prolate trochoid)。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果黑点在圆内部,它就是短幅次摆线(Curtate trochoids)。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

为了做出这些动画,我让圆从左向右运动,计算出每个位置上圆的旋转角度,用 sine 和 cosine 基于圆的位置与旋转角度计算出点的位置,然后用这些点画出线。但对于次摆线其实有更直接的公式

x = a * t - b * sin(t)
y = a - b * cos(t)

t 是圆的旋转角度,它可以无限增长, a 是圆的半径, b 是圆心点至绘制点的距离 - 可以说是那个点的半径。让我们把它实现出来:

width = 800
height = 300
canvas(width, height)
 
translate(0, height/2)
scale(1, -1)
moveTo(0, 0)
lineTo(width, 0)
stroke()
 
a = 20.0
b = 20.0
res = 0.05
 
for (t = 0.0; t < width; t += res) {
    x = a * t - b * sin(t)
    y = a - b * cos(t)
    lineTo(x, y)
}
stroke()

公式是基于笛卡尔坐标的,我们要将 y 轴移至 canvas 中心,并将 y 轴翻转。

然后画一条直线从 y 轴中心穿过用于表示圆滚动时的“地面”。你可以画也可以选择不画。

我们将 a 和 b 都设为 20, 这样就可以得到摆线(译者者:普通旋转线)了。我们循环将从 0 至 canvas 的宽度用于变量 t, 应用公式连接至计算出的结果点。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果将 b 提高到 60, 我们就得到了长幅摆线

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果将 b 减小到 10, 我们就得到了短幅摆线。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

我不知道长幅摆线和短幅摆线的用词是否准确,但听起来挺酷。

这就是全部关于次摆线的内容。试试给 a 和 b 设不同的值,或者你自己改一下其它值,我就不再再多讲了。因为下面还留有很多旋轮曲线需要探讨。

中心次摆线

接下来我们要聚焦于被称为中心次摆线的四种曲线。与延直线滚动不同,它是延另一个圆滚动,可能是延那个圆圆内部滚动也可能是延那个圆的外部滚动。

四类分别是:

  • Epicycloids 外摆线 - 延一个圆外部滚动的圆,圆周上某一点轨迹形成的曲线。
  • Epitrochoids 长短辐外摆线 - 与上面一个一样,但这个点是不在圆周上,而是在圆外或圆内,与短幅次摆线与长幅次摆线一样。
  • Hypocycloids 内摆线 - 延一个圆内部滚动的圆,圆周上某一点轨迹形成的曲线。
  • Hypotrochoids 长短辐内摆线 - 与上面那个一样,但这个点是不在圆周上,而是在圆外或圆内

除此之外,还有一些曲线也是属于上面曲线的一种变体,只是形成曲线的两个圆半径有特殊的比例关系。我们稍后会看介绍一些。

Epitrochoids 长短辐外摆线

首先,让我们将一个圆延另一个圆外滚动可视化
曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

再追踪一下那个黑色的点的绘制结果

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

这就是你长短辐外摆线!

事实上,由于那个点是在圆周位置上,所以这也就是外摆线!

如果将点往外移动一点...

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

再我们往内移动一点。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

再一次,我创建这些动画是通过计算这些圆的位置,绘制这些圆,再计算这些圆的旋转角度并绘制对应的点, 然后再连接每一帧所绘制的点路径形成曲线。为了展示动画像这么做是值得的,但是其实是有更简单的公式,你可以直接应用:

长短辐外摆线公式:

x = (r0 + r1) * cos(t) - d * cos(((r0 + r1) * t) / r1)
y = (r0 + r1) * sin(t) - d * sin(((r0 + r1) * t) / r1)

参数解析:

  • r0 是定圆的半径
  • r1 是动圆的半径
  • t 是增长的弧度
  • d 是动圆中心点与绘制点之间的距离 (如果是外摆线则 r1 与 d 相同)

我们用这个公式瞬间就可以用些代码实现:

width = 800
height = 800
canvas(width, height)
 
translate(width/2, height/2)
 
r0 = 180
r1 = 60
d = 60
res = 0.01
 
circle(0, 0, r0)
stroke()
 
for (t = 0.0; t < PI * 2; t += res) {
  x = (r0 + r1) * cos(t) - d * cos(((r0 + r1) * t) / r1)
  y = (r0 + r1) * sin(t) - d * sin(((r0 + r1) * t) / r1)    
  lineTo(x, y)
}
stroke()

我们设置变量 r0, r1, d 然后绘制定圆仅仅是为了引用变量

接着循环 t 至 2 * PI, 得到 x, y 点,绘制一条线至那个点。

得到结果:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

值得注意的一点, ro 到 r1 的比例。 180:60 或 3:1。 我们得到3个结点。如果将 r1 改为 45,比例即变为 4:1 , 我们将得到 4 个结点。(我将 d 变为 45 也是为了适配 r1)

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

下面是 12:1 :

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果比例的第二个数字不是1,会如何?让我们将 r0 设置为 150,r1 为 100。现在,ratio 为 3:2。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

毫无意外,我们得到了一个半的结点(nodes)。为了完成这个曲线,我们不得不再绕一圈,需要将 t 的范围值变为 0 到 PI * 4。然后得到结果:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果你使用整数,循环总是会完成的。在下一个例子中,比如是 11:7 ,所以不得不将 t 结束值调整为 PI * 14:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果是 111:70, 意味着我需要 t 结束范围调整至 140 * PI:

手动算这个有点痛苦,你可以创建个函数简化比例计算并用分母 * PI * 2 作为循环次数。 下面有两个有用的函数

//(译者注: gcd 即 greatest common divisor 求最大公约数)
function gcd(x, y) {
  result min(x, y)
  while (result > 0) {
    if (x % result == 0 && y % result == 0) {
      break
    }
    result--
  }
  return result
}
 
function simplify(x, y) {
  g = gcd(x, y)
  return x / g, y / g
}

仅需要将 r0 和 r1 传入 simplify 函数,得到简化后的比例。将结果的第二个数字 * 2 * PI 做为循环的结束条件。下面是例子...

(译得注:简化比例式,最后将分母 * 2 * PI)

width = 800
height = 800
canvas(width, height)
 
translate(width/2, height/2)
 
r0 = 111
r1 = 70
d = 70
res = 0.01
num, den = simplify(r0, r1)
 
circle(0, 0, r0)
stroke()
 
for (t = 0.0; t < PI * 2 * den; t += res) {
  x = (r0 + r1) * cos(t) - d * cos(((r0 + r1) * t) / r1)
  y = (r0 + r1) * sin(t) - d * sin(((r0 + r1) * t) / r1)    
  lineTo(x, y)
}
stroke()

用化简后的分数的分母保证循环足够多闪以形成完整的曲线。

到目前为止,全部是外摆线(圆外旋轮线)。 让我们改变参数 d 来创建一些其它的长短幅外摆线。

让 d 大于 r1:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

d 小于 r1:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

在这些例子中我没有再把内圆画出来。

你无需让我再提供更多的例子了。只需要改变数字看看能得到啥结果。

特殊长短幅外摆线

蚶线是长短幅摆线的一种,生成它的两个圆半径相等。如果两个点在圆内,则它是特殊的蚶线被称为 Cardioid 心形曲线。

下面是一个蚶线,两个半径都是 80 , d 值设为 160。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

心形线三个值都设为 80

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

肾脏线是长短幅外摆线的一类,它的定圆半径是动圆半径的2倍,且那个点在动圆的圆周上。这是肾脏线的图

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

你也可以让那个动圆上的点不在动圆圆周上,但却不再是肾脏线了,但依然是很不错的曲线。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

现在让我们把视线转向长短幅内摆线!

长短幅内摆线

正如前面提到的,长短幅内摆线其实就是动圆是延定圆内部滚动的。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

我们跟踪那个曲线上的绘制点,就得到了长短幅内摆线

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

事实上,由于绘制点在动圆圆周上,它就是内摆线。

当绘制点移动到动圆外部, 得到的就是:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

当绘制点移到动圆内部...

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

像之前一样,这个动画是用野路子创建的,其实是有简单公式可以实现。

长短幅内摆线公式:

x = (r0 - r1) * cos(t) + d * cos(((r0 - r1) * t) / r1)
y = (r0 - r1) * sin(t) - d * sin(((r0 - r1) * t) / r1)

参数与长短幅外摆线类似,事实上公式也基本相同,仅有几项符号不同。

下面是使用方法。

width = 800
height = 800
canvas(width, height)
 
translate(width/2, height/2)
 
r0 = 300
r1 = 50
d = 50
res = 0.01
num, den = simplify(r0, r1)
 
for (t = 0.0; t < PI * 2 * den; t += res) {
  x = (r0 - r1) * cos(t) + d * cos(((r0 - r1) * t) / r1)
  y = (r0 - r1) * sin(t) - d * sin(((r0 - r1) * t) / r1)
}
stroke()

代码运行结果:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

注意 r0 与 r1 比例是 6:1, 拥有 6 个点。比例的作用原理与之前的长短幅外摆线一样

下面是半径 312 和 76 (译者注:这里 r0 为 312,r1,d 都为 76):

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

将绘制点 d 值设大一点移出动圆圆周:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

移入动圆内...

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果你不断尝试,我保证你能发掘出更多有趣的图形。

特殊长短幅内摆线

我将再介绍两种特殊长短幅内摆线。我们需要再次调整两个圆的大小比例。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

这是星状图的比例 4:1

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

还有一个更有趣的比例 2:1. 被称为图斯双圆,以描述它的13世纪波斯天文学家名字而命名。下面是演示它的动画。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

正如你所看到的,形成了一条直线。

如果你多创建几个动圆,并将每个动圆的绘制点相位与前一个相比再往后调整一点,你将会得到如下图:

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

每个点延直线来回运动。如果你将所有线条和动圆移除,你会得到一个旋转的圆的错觉。事实上,它看起来像是另一个内摆线

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

螺旋图!

小时候如果你像我一样比较呆,那么你可能也会像我这样拥有下面这些东西(译者注:可能我不够呆,反正我没有过,倒是见过同学有类似的东西--!):

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

这是几个星期前为写这一章内容我新买的。它很酷,锡盒子包装内包含了一些绘制用的纸还有使用说明和灵感小册子。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

大的齿轮固定在纸上。过去用的是小钉子,现在用的是用粘粘的东西(sticky-tack 多伟大的改进!)固定住,还有一些小的多孔的小齿轮。你将笔插进这些小孔中,让它延着大圆旋转一圈。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

瞧!一个长短幅内摆线

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

如果你将小齿轮摆外面滚一轮,它就是长短幅外摆线。相当有趣,说实施,我还是更喜欢用代码实现它。下面是绘制过程中笔滑了,这让线条看起来有点儿乱。笔触也断断续续的。

曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

当我玩的过程中才发现,它只能画出短幅摆线和内摆线。绘制点只能是在移动的齿轮内。

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


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

到了这里,关于曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索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)
  • 第九章 JUC并发编程

    http://t.csdn.cn/UgzQi 使用 AQS加 Lock 接口实现简单的不可重入锁 早期程序员会自己通过一种同步器去实现另一种相近的同步器,例如用可重入锁去实现信号量,或反之。这显然不够优雅,于是在 JSR166(java 规范提案)中创建了 AQS,提供了这种通用的同步器机制。 AQS 要实现的功能

    2023年04月08日
    浏览(40)
  • 第九章 shell 编程

    第九章 shell 编程 一、 编写与执行 Shell 脚本 • shell 脚本的作用类似于 DOS 的批处理文件,但无文件名规定。 • shell 脚本是文本文件,可用 vi、gedit 或其它文本编辑去创建。 • 脚本的首行应是#!/bin/sh,指明该用什么程序来解释该脚本。 • 使用 chmod +x 命令为脚本文件增加可

    2024年02月06日
    浏览(63)
  • 《TCP IP网路编程》第九章

            我们进行套接字编程时往往只关注数据通信,而忽略了 套接字具有的不同特性 。但是,理解这些特性并根据实际需要进行更改也很重要。下面列出了一些 套接字可选项 。         从表中可以看出,套接字可选项是分层的。 IPPROTO_IP 可选项是IP协议相关事项

    2024年02月16日
    浏览(38)
  • 《Opencv3编程入门》学习笔记—第九章

    记录一下在学习《Opencv3编程入门》这本书时遇到的问题或重要的知识点。 一、图像直方图概述 1、作用:   在每个兴趣点设置一个有相近特征的直方图所构成的标签,通过标记帧与帧之间显著的边缘、颜色、角度等特征的统计变化,来检测视频中场景的变化。 2、概念:

    2024年02月11日
    浏览(48)
  • C Primer Plus第九章编程练习答案

    学完C语言之后,我就去阅读《C Primer Plus》这本经典的C语言书籍,对每一章的编程练习题都做了相关的解答,仅仅代表着我个人的解答思路,如有错误,请各位大佬帮忙点出! 1.设计一个函数min(x, y),返回两个double类型值的较小值。在一个简单 的驱动程序中测试该函数。 2

    2024年02月06日
    浏览(43)
  • java JUC并发编程 第九章 对象内存布局与对象头

    第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 第六章 java JUC并发编程 CAS: link 第七章 java JUC并发编程 原子操作类增强: link 第八章

    2024年02月07日
    浏览(44)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包