首页 > 编程语言 >曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)

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

时间:2023-06-13 13:22:05浏览次数:45  
标签:r0 r1 曲线 coding 旋轮 摆线 width 长短

第九章 旋轮曲线(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 次摆线

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

image

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

image

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

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

image

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

image

为了做出这些动画,我让圆从左向右运动,计算出每个位置上圆的旋转角度,用 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, 应用公式连接至计算出的结果点。

image

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

image

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

image

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

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

中心次摆线

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

四类分别是:

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

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

Epitrochoids 长短辐外摆线

首先,让我们将一个圆延另一个圆外滚动可视化
image

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

image

这就是你长短辐外摆线!

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

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

image

再我们往内移动一点。

image

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

长短辐外摆线公式:

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 点,绘制一条线至那个点。

得到结果:

image

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

image

下面是 12:1 :

image

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

image

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

image

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

image

如果是 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:

image

d 小于 r1:

image

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

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

特殊长短幅外摆线

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

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

image

心形线三个值都设为 80

image

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

image

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

image

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

长短幅内摆线

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

image

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

image

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

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

image

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

image

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

长短幅内摆线公式:

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()

代码运行结果:

image

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

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

image

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

image

移入动圆内...

image

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

特殊长短幅内摆线

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

image

这是星状图的比例 4:1

image

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

image

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

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

image

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

image

螺旋图!

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

image

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

image

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

image

瞧!一个长短幅内摆线

image

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

image

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

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


博客园: http://cnblogs.com/willian/
github: https://github.com/willian12345/

标签:r0,r1,曲线,coding,旋轮,摆线,width,长短
From: https://www.cnblogs.com/willian/p/17477255.html

相关文章

  • 圆锥曲线和直线
    高中选择性必修一内容省流:独立发现妙妙结论\(\Delta=A^2a^2+B^2b^2-C^2\)引子我是一个热爱过程的人,但是很明显我不爱计算所以我有言曰:遇到一个很通用的题目,我们要先苦后甜,先把字面的数字用字母换了,再代入计算。然后我们把目光放到高中选择性必修一第114页(臭)的一道例题:......
  • g2o优化库实现曲线拟合
    g2o优化库实现曲线拟合最近学习了一下g20优化库的基本使用,尝试着自己写了一个曲线拟合的函数,也就是下面这个多项式函数:\[y=ax^3+bx^2+cx+d\]我们以\(a=3,b=-2,c=5,b=7\)为例,拟合出的图像大概长这样。下面简单记录一下思路:目标函数:\[\min_{a,b,c,d}\fra......
  • 使用Getdata软件抓取曲线数据
    1.打开Getdata,点击“File”--->“OpenImage”注:图片格式尽量为jpg,当然tifbmppcx也可以。2.定义x,y坐标光标点原点--->右击--->"SetXmin"--->设置Xmin值(这里我随便取的,如果要修改,可以:“Operations”--->“Adjustthescale”)或者直接点击小图标。光标点x末......
  • echarts 曲线图组件
    样式如图使用:     <echartLine      ref="day30Echat"      :xAxis="timeList"      :xlist="xlist30Day"      :xlist2="xlist230Day"      :smooth="true"     ><......
  • # yyds干货盘点 # Python中encoding='utf-8-sig'是什么意思
    大家好,我是皮皮。一、前言前几天在Python白银群【凡人不烦人】问了一个Python编码的问题,这里拿出来给大家分享下。二、实现过程这里大家一起来学习下。在Python中,encoding='utf-8-sig' 是一种编码格式,用于指定字符串的编码方式。具体来说,utf-8-sig 编码格式是 utf-8 编码的一种......
  • 【IDE】IntelliJ IDEA 插件之Alibaba Java Coding Guidelines - 阿里巴巴Java代码检测
    一、安装进入插件安装界面|-File |-Settings |-Plugins输入alibabainstallAlibabaJavaCodingGuidelines重启IDEA,开始使用二、使用编码规范扫描该插件在扫描代码后,将不符合《java开发手册》的代码按Blocker/Critical/Major三个等级进行显示在Snoar中对代码规则有五......
  • 技术革命的 S 型发展曲线
    前些天Nvidia的发布会,除了怪物一样的GH200超级芯片,给我印象最深的是这几次技术革命的S型发展曲线。NVIDIA是一家美国计算机科技公司,成立于1993年,总部位于加利福尼亚州的圣克拉拉市。它主要从事GPU(图形处理器)方面的研究、设计及制造,旨在为游戏、专业图形、人工智能、数据中......
  • 绘制Bezier曲线(Windows GDI)
    本文仅记录绘制贝塞尔曲线的代码写法,不解释贝塞尔曲线本身。若要了解贝塞尔曲线本身你需要具备一些基础知识:基本空间几何知识排列组合常用等式贝塞尔曲线的数学表达式了解Bernstein基函数贝塞尔曲线的各种绘制方法本文使用递推方法绘制。就像这图上显示的:代码的核心部分......
  • 曲线艺术编程 coding curves 第三章 弧,圆,椭圆(ARCS, CIRCLES, ELLIPSES)
    第三章弧,圆,椭圆(TRIGCURVES)原作:KeithPetershttps://www.bit-101.com/blog/2022/11/coding-curves/译者:池中物王二狗(sheldon)blog:http://cnblogs.com/willian/源码:github:https://github.com/willian12345/coding-curves曲线艺术编程系列第三章在这一篇中我......
  • 曲线艺术编程 coding curves 第二章 三角函数曲线(TRIG CURVES)
    第二章三角函数曲线(TRIGCURVES)原作:KeithPeters原文:https://www.bit-101.com/blog/2022/11/coding-curves/译者:池中物王二狗(sheldon)blog:http://cnblogs.com/willian/源码:github:https://github.com/willian12345/coding-curves曲线艺术编程系列第二章这是与曲线......