65.9K
CodeProject 正在变化。 阅读更多。
Home

齿轮图曲线 - 第二部分。

starIconstarIconstarIconstarIconstarIcon

5.00/5 (8投票s)

2018年3月16日

CPOL

6分钟阅读

viewsIcon

10549

downloadIcon

213

继续定义和展示从最简单到最迷人的齿轮曲线。提供用于说明其不同方面的网页和 R 脚本。

引言

本文的目标是继续定义和展示在“第一部分”[1]中开始的齿轮曲线。

在本部分中,将讨论一些有趣的 R 脚本发现,还将介绍基于 JavaScript 的多齿轮曲线解决方案。

齿轮曲线方程的基本形式仍然是以下形式:

x = R0*cos(T0*t) + R1*cos(T1*t),
y = R0*sin(T0*t) - R1*sin(T1*t),

其中

  • R0,T0 - 与第一个齿轮半径和角度 t (theta) 相关的系数
  • R1,T1 - 与第二个齿轮半径和角度 t (theta) 相关的系数

注意:我们允许所有系数为负。

这些方程同时用于 R 语言(用于 2 个齿轮)和 JavaScript(用于多个齿轮)。

在附件的GGCArtp2.zip文件中,可以找到与本文相关的所有 R 脚本和网页。

最后提醒

我想向读者保证,我了解所有相关文章,至少,那些来自可靠在线来源的文章。

许多来源使用的公式相似,但实际上不同,并且使用不同的绘图技术,包括不同的语言和工具,例如 [3]。

其他则非常优秀、专业的实现(例如 [4,5]),但它们肯定不适合初学者。只需看一下提供的源代码 [4],然后比较此处和 [4] 中的 JavaScript 大小。

R 中的齿轮曲线

在 R 中生成和绘制齿轮曲线不需要做任何不同的事情。确实,这只是“翻译”JavaScript 到 R。

在下面的 R 代码中,可以找到用于生成和绘制齿轮曲线(2 个齿轮)的完整版本函数。此外,还有几个使用此函数的示例。

## GG2g(): GearoGraph - 2 gears. Curves are plotted with lines (line segments)
#  Where: n - lines, r0,r1 - 1st and 2nd gear radius scales; t0,t1 - theta
#         scales; fn - file name (no extension); cfg - color FG;
#         ttl - plot title; psz - max square picture size; cbg - color BG.
#
GG2g <- function(n,r0,t0,r1,t1,fn, cfg="maroon", ttl="", psz=640, cbg="white"){
  pf = paste0(fn, ".png");
  # Plotting
  par(bg=cbg); it=pi*2/n; t=seq(0,n,it);
  x=(r0*cos(t0*t)+r1*cos(t1*t));
  y=(r0*sin(t0*t)-r1*sin(t1*t));
  if (ttl!="") {
    plot(x,y, type="l", main=ttl, axes=FALSE, xlab="", ylab="", col=cfg)}
  else {par(mar=rep(2,4)); par(plt=c(0,1,0,1));
    par(xpd = NA); par(oma=rep(2,4), xaxs='i', yaxs='i');
    plot(x,y, type="l", axes=FALSE, col=cfg)};
  # Writing png-file
  dev.copy(png, filename=pf, width=psz, height=psz);
  # Cleaning
  dev.off(); graphics.off();
}
# GG2g(4000,240,1,235,400,"GG2gR01","navy","", 1280); ##  Flower head
# GG2g(2000,200,1,150,330,"GG2gR02","darkgreen","", 1280); ## Many trees (from center)
# GG2g(3013,243,1,53,610,"GG2gR03c","maroon","", 1280); ## Engraved ring

下面图示了 3 条齿轮曲线(“花头”、“树木”和“雕刻环”)。

Flower head Trees Engraved ring

图 1:3 条齿轮曲线(2 个齿轮)

这里有一个有趣的问题:“如果我们想用点而不是线段来绘制齿轮曲线怎么办?” 新函数几乎是 `GG2g()` 函数的孪生(不完全相同)。只有 3 行 R 代码不同。请参阅下面的代码片段。

## 1st line - different name of function
## GG2gd <- function(n,r0,t0,r1,t1,fn, cfg="maroon", ttl="", psz=640, cbg="white"){

## 2nd line - different 1st plot statement
    plot(x,y, main=ttl, axes=FALSE, xlab="", ylab="", col=cfg, pch=20)}

## 3rd line - different 2nd plot statement
    plot(x,y, axes=FALSE, col=cfg, pch=20)};

让我们使用这两个函数生成并绘制一个漂亮的环(看起来像 3D 雕刻环),再加上额外的“树木”曲线(在图 1 中,我们是用线绘制的)。

GG2g(2000,250,1,50,500,"GG2gRcr","darkred","Carved ring (in lines)", 1280);
GG2gd(2000,250,1,50,500,"GG2gRdcr","darkred","Carved ring (in dots)", 1280);
## additional curve "Trees" using dots
GG2gd(2000,200,1,150,330,"GG2gdmt","darkgreen","", 1280);  # Trees (in dots)

下面显示了所有 3 条结果曲线。

Carved ring (in lines) Carved ring (in dots) Trees (in dots)

图 2:3 条齿轮曲线(用线和点表示)

现在,这两个用点绘制的曲线不仅不好看,而且还令人困惑和误导。尽管事实上,绘图是正确的!

在这里,我们重新发现了这样一个有趣的现象:使用线段或点绘制连续曲线是不同的。
例如

  • 在 [2] 中,强调了 H. Vogel 发现“向日葵籽图案”,仅仅因为他使用大点来绘制他的螺旋线。
  • 在这里,我们有相反的效果:应该使用线段来绘制“真实”的齿轮曲线。使用点绘制是不正确的,但至少可以帮助理解绘图“点”和其他细节,例如阴影、“雕刻”等。

关于 R 中绘图的总结

请注意,在 R 中绘制齿轮曲线

  • 比使用 [1] 中的“生成器”页面花费的时间更多。
  • 要测试许多曲线需要准备具有不同参数的函数调用,但在“生成器”页面中,可以更快地完成,只需单击几下即可获得下一条曲线。
  • 建议至少将画布尺寸设置为双倍(即 1280),因为 R 中的缩放方式不同。例如,要在“森林”中找到“树木”,用户应该查看图 1 中显示的“树木”子图的完整尺寸。

绘制多齿轮的齿轮曲线

使用多个齿轮的想法已在许多在线资源中提出(例如 [3-5] 和许多其他资源)。

在 [3] 中,发布了 C# 代码,该代码易于“翻译”到 JavaScript 并转换为我们的方程。请参阅下面的 C# 代码片段(“按原样”)。

  // each line in the grid is like adding a wheel to a spirograph toy,
  // we just add up where each "wheel" move the point
  for (i = 0; i < max; i++)
  {
    rx += radius[i] * Math.Cos(speed[i] * (angle + phase[i]));
    ry += radius[i] * Math.Sin(speed[i] * (angle + phase[i]));
  }

下面显示了已“翻译”成 JavaScript 并转换为我们方程的代码片段。

// global vars
  var cvs, ctx, cw, cc; // canvas: context, width, center
  var cfg, cbg;         // colors: FG & BG
  var pi2=Math.PI*2, gn, msro;
//*****
  // Plot loop
  for (var i=0; i<=n; i++) {
    t=i*it;
 	x = R[0] * Math.cos(T[0]*t);
	y = R[0] * Math.sin(T[0]*t);

	for (var g=1; g<gn; g++) {
	  x += R[g] * Math.cos(T[g]*t);
	  y -= R[g] * Math.sin(T[g]*t); }
    x=x*sc+cc+sx; y=y*sc+cc+sy;
    ctx.lineTo(x, y);
  }

注意:理论上可以使用无限数量的齿轮,但实际上测试起来会非常困难。

使用齿轮曲线生成器网页

“齿轮曲线生成器(多齿轮)”网页(GGmgGenerator.html)包含在 zip 文件中,并在下面的图 3 中(部分)显示。

GGmgGenerator.html page.

图 3:GGmgGenerator.html 页面。

如上所述,此页面允许输入几乎所有控制齿轮曲线绘图的参数,并可以生成和显示所有可能的齿轮曲线(多齿轮)。

值得一提的是,输入向量 - R, T - 的大小和语法都会被检查。如果出现错误,会在画布区域上方以红色显示相应的错误消息(有时会令人困惑)。请参见上面图 3 中的示例消息。

首先,请看下面的图 4,其中显示了 6 条选定的曲线。注意:用于绘制子图的输入参数可以在GGCmgTestSamples.txt文件中找到。

1234903/GGC2g01.png 1234903/GGC3g01.png 1234903/GGC4g01.png

1234903/GGC5g01.png 1234903/GGC6g01.png 1234903/GGC9g01.png

图 4:选定的齿轮曲线(多齿轮)

图 4 的子图如下:

  • 子图 1-3(2、3 和 4 个齿轮)
  • 子图 4-6(5、6 和 9 个齿轮)

现在,请加载页面并按照“第一部分”[1]中的建议进行测试。

附件的 zip 文件中包含一个相当大的GGCmgTestSamples.txt文件。它肯定会对您进行测试有所帮助。

结论

在测试“生成器(多齿轮)”页面时,用户一定会发现以下特点/属性:

  • 当齿轮数量超过 3 个时,很难预测曲线。
  • 与此同时,最终发现了许多新的有趣图案。
  • 如果向量 T 的所有值都很大(例如,所有 T[i]>200),那么曲线就会变得非常混乱。在极少数情况下,增加画布尺寸可能有助于看到任何图案。

我(希望)从这个并不那么复杂的页面上学到的额外知识如下:

  • 如何检查输入向量的大小和语法
  • 如何将曲线拟合到画布中并将其置于画布中心
  • “生成器”页面的测试策略。请参阅GGCmgTestSamples.txt文件中的示例。

以下是一些即使是初学者也能非常非常非常轻松实现的传统练习!

练习 #1:创建Demo3.html页面,该页面生成并演示 10-12 条选定的多齿轮绘制的齿轮曲线。使用GGmgGenerator.htmlGG2gDemo2.htmlGGD2.js的原始代码。
练习 #2:创建MyCurveGenerator.html页面。使用GG2gGenerator.html页面的原始代码。注意:要使任何曲线循环,方程中应使用 sin(theta), cos(theta)。任何其他细节由您自行决定。

享受齿轮曲线的乐趣!

参考文献

  1. Voevudko, A.E. (2018) 齿轮曲线 - 第一部分。Code Project,网址:https://codeproject.org.cn/Articles/1233760/Gearographic-Curves-Part
  2. Voevudko, A.E. (2017) Vogel 螺旋现象。Code Project,网址:https://codeproject.org.cn/Articles/1221341/The-Vogel-Spiral-Phenomenon。
  3. arussell, J. (2013) 内摆线/花样。Code Project,网址:https://codeproject.org.cn/Tips/656968/Hypotrochoid-Spirograph。
  4. SEEDcode. (2016) SpirographN:在线生成器(多齿轮)。网址:http://seedcode.com/SpirographN/sgn.html。
  5. Whitehouse, J. (2012) 花样图案。在线生成器(多齿轮)。网址:http://www.eddaardvark.co.uk/python_patterns/spirograph.html。
© . All rights reserved.