码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 曲线艺术编程 coding curves 第十二章 玑镂(扭索)纹


    合集 - 曲线编程艺术(14)
    1.曲线艺术编程 coding curves 第二章 三角函数曲线(TRIG CURVES)06-012.曲线艺术编程第一章 coding curves06-013.曲线艺术编程 coding curves 第三章 弧,圆,椭圆(ARCS, CIRCLES, ELLIPSES)06-024.曲线艺术编程 coding curves 第四章 利萨茹曲线(Lissajous Curves)06-035.曲线艺术编程 coding curves 第五章 谐波图形(谐振图形) HARMONOGRAPHS06-066.曲线艺术编程 coding curves 第六章 平托图 (Pintographs)06-087.曲线艺术编程 coding curves 第七章 抛物线(Parabolas)06-108.曲线艺术编程 coding curves 第八章 贝赛尔曲线(Bézier Curves)06-129.曲线艺术编程 coding curves 第九章 旋轮曲线(ROULETTE CURVES)06-1310.曲线艺术编程 coding curves 第十章 螺旋曲线(SPIRALS)06-1411.曲线艺术编程 coding curves 第十一章 玫瑰花形( ROSES)06-16
    12.曲线艺术编程 coding curves 第十二章 玑镂(扭索)纹06-19
    13.曲线艺术编程 coding curves 第十三章 超级椭圆与超级方程(Superellipses and Superformulas)06-2414.曲线艺术编程 coding curves 第十四章 其它曲线(Miscellaneous Curves)07-05
    收起

    第十二章 玑镂(扭索)纹

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

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

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

    曲线艺术编程系列 第 12 章

    玑镂纹是一种错综复杂且非常迷人的图案。它经常被绘制在银行钞票和官方文档上,你也可以在手表表盘或其它复杂机械上找到它们的身影。正因为它们如此复杂难以理解,所以它们经常被镌刻在金属表面,这通常是由机器来完成。想象一下一台高端螺旋仪用金属刻蚀工具代替原本用于绘图的圆珠笔。“玑镂纹” 这词相当模糊,它可以代称所有这一类纹理。我将要讲解的是如下图案中的玑镂纹理:

    image

    这个纹理你可能已经在某种证书或钞票上见过了,一旦你知道生成原理,你就可以以调整代码的方式生成另外相似的纹理图案。

    第一步:创建一个单独的圆

    我们先从创建单个简单的圆开始,它看起来应该像下面这样:

    image

    它非常像一个摆线或玫瑰曲线。事实上你可以通过它们的公式创建它,但我将改动一点点,以便后面处理更复杂的纹理图案。

    本质上是一个正弦波包住一个圆。注意它有一个内半径和一个外半径。 这个正弦波有 80 个 nodes,它自身波纹会重叠。为了更好的解析,我将增大内半径让它不再重叠:

    image

    现在可以看的更清楚了。正如我所说的那样,一个正弦波包住一个圆。现在我要再加一点点重叠纹理:

    image

    图中虽然有重叠部分你仍然可以观察到正弦波。第一张图像用的是同样的原理,只是内半径更小且重叠部分更多。现在我让我们看看是如何绘制的。

    我们先设内半径 inner 与外半径 outer 开始。通过简单的数学运算得到 mid 半径。它将是正弦波的零点。我们还需要一个范围,它决定了正弦波在内外半径扩展的范围。你也可以称它为这个正弦波的振幅。

    width = 600
    height = 600
    canvas(width, height)
     
    translate(width / 2, height / 2)
     
    inner = 50
    outer = 250
    range = (outer - inner) * 0.5
    mid = inner + range
    

    下一步,我们需要知道要多少个波形周期,还有多少次重叠。我将把它们称作 nodes 和 div, 它们应该是整数且两个数不能被整除。 这非常像上一章玫瑰曲线中遇到的 n 和 d 参数, 但为了不混淆我会用另外的变量名。

    nodes = 80
    div = 11
    

    现在我们可以循环 t 到 2 * PI * div 并绘制一些线段。 下一个线段坐标点角度简单的用 t 和 半径 radius 计算得出。我们需要将循环结束条件 2 * PI 再乘以 div 以确保足够绕一圈,首尾可以相连。

    for (t = 0; t < 2 * PI * div; t += 0.01) {
      radius = mid + sin(t * nodes / div) * range
      x = cos(t) * radius
      y = sin(t) * radius
      lineTo(x, y)
    }
    stroke()
    

    如果你回头看玫瑰曲线那一章, 你会发现它们都是用相似的方法计算半径值的, 但相比使用正弦和单一的乘法,我们使用 mid 和 range 调整半径至内半径与外半径之间。

    你可以多玩玩。试试改动不同的参数。为了生成一个比较好看的玑镂纹,你可能需要将 nodes 设高一点,div 低一点。最重要的是它们的值不能被整除。想要得到比较得体的图案,一个比较简单的方法是让 div 是一个小的质数, nodes 不能是 div 的倍数。

    举个例子,如果 div 是 17,你不应该将 nodes 设为 170,否则你将会得到如下图:

    image

    但将 nodes 增加到 171 则会得到很好的图案:

    image

    如果你想玩的话,我几年前做了一个可交互的版本:

    https://bit101.github.io/lab/dailies/170120.html

    接下来,我们在混合当中再添加一些复杂性。相比在固定的内外半径来回绘制正弦波,我们在内外半径各自添加正弦波变化!结果如下图:

    image

    为此我们需要更多的参数。为了计算出最终外半径上任意一点,我们需要基于外半径,计算有多少正弦波周期和最终外半径与基础外半径的距离差。那么内半径同样需要3个值,nodes 与 div 也依然要。上图中我使用的参数值如下:

    inner = 100.0
    n0 = 7.0
    h0 = 10.0
     
    outer = 250.0
    n1 = 17.0
    h1 = 20.0
     
    nodes = 142.0
    div = 89.0
    

    内半径有 7 nodes, 半径范围在 90 - 110 之间,它是基于100 加减 10。然后,同样,外半径有 17 个 nodes ,半径范围在 230 - 270 之间。

    在 for 循环迭代内之前计算 "mid radius" 的相关代码用这些值重写。

    for (t = 0; t < 2 * PI * div; t += 0.01) {
      r0 = inner + sin(t * n0) * h0
      r1 = outer + sin(t * n1) * h1
     
      range = (r1 - r0) * 0.5
      mid = r0 + range
     
      radius = mid + sin(t * nodes / div) * range
      x = cos(t) * radius
      y = sin(t) * radius
      lineTo(x, y)
    }
    stroke()
    

    当然你可以对以上代码进行简化,但为了清晰起见我把每步都写出来了。

    你可以继续改动这些参数,看看能创造出什么样的图形。我们还有更复杂的一级要处理。

    https://bit101.github.io/lab/dailies/170121.html

    第三步 多环

    下一步是创造多环,这些环相互配合在一起, 就像章节开头的那张图:

    image

    它的实现比看起来人简单的多。如果你想绘制小环外围绕大环,你仅需要将小环的外半径作为大环的内半径。由于我们会多次调用相同的代码,最好把它变成可复用的函数。基本上就是把 for 循环和 stroke 调用 放入一个可传所有参数函数中。我还添加了 x, y 参数, 这样你就可以把图绘制在 canvas 的任意位置了。

    function guilloche(x, y, ir, n0, h0, or, n1, h1, nodes, div) {
      for (t = 0; t < 2 * PI * div; t += 0.01) {
        r0 = ir + sin(t * n0) * h0
        r1 = or + sin(t * n1) * h1
     
        range = (r1 - r0) * 0.5
        mid = r0 + range
     
        radius = mid + sin(t * nodes / div) * range
        lineTo(x +cos(t) * radius, y +sin(t) * radius)
      }
      stroke()
    }
    

    我把 canvas 宽高调整为 800x800 并且像下面这样调用代码:

    guillloche(400, 400, 50, 6, 10, 120, 12, 20, 137, 37)
    guillloche(400, 400, 120, 12, 20, 220, 18, 30, 141, 41)
    guillloche(400, 400, 220, 18, 30, 350, 24, 20, 164, 53)
    

    This resulted in the following image:

    结果如图:

    image

    注意第一行调用,外半径参数是 120, 12,和 20。 这些作为下一个调用的内半径参数。第二个调用的外半径参数 220, 18 和 30, 作为最后一个调用的内半径参数。像这样做后,绘制出的环简直完美。

    像往常一样你应该多调调参数,多试试。你可以想加多少环就加多少环。你也许希望把所有半径参数封装成自定义类型结构体让这部分变的更有复用性。我将把这部分工作留给你。

    另外你可能想给各个一觉不同的颜色:

    image

    (译者注:我添加了随机颜色源码在 https://github.com/willian12345/coding-curves/tree/main/examples/ch12/guilloche-colorful.html)

    这里有一个可交互的最终版本:

    https://bit101.github.io/lab/dailies/170122.html

    注意,这里可没有说环与环之间必须要紧密相扣。你可以试着给它们之间留点距离或者让它们重叠一部分看看你能创造出多有趣的图案。下一个例子中,第一个与最后一个环与之前例子中设置的一样, 但中间这个环的参数定义的相当不同:

    guillloche(400, 400, 20, 4, 5, 120, 8, 10, 137, 37)
    guillloche(400, 400, 160, 5, 24, 160, 11, 24, 80, 17)
    guillloche(400, 400, 220, 18, 16, 350, 10, 20, 164, 53)
    

    此处,内外半径值相等,都是 160,生成比简单的离散环更有趣的团状环。

    image

    还有,别忘了把它做成动画!

    image

    总结

    你用 Guilloche patterns 关键词搜索图片,会得到非常多不同样式的图,大部分比我这里讲的要复杂的多。我只是从中挑了一个来讲。

    也许你想尝试修改代码绘制其它形状的玑镂纹,也许从椭圆形玑镂是个不错的开始。然后再开始绘制其它形状。但这些内容都超出本章范围了。

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


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

  • 相关阅读:
    Linux 报错:failed to run command ‘java’: No such file or directory
    开篇-开启全新的.NET现代应用开发体验
    深度学习的数值问题
    Ubuntu 搭建小熊派 hi3861 环境
    QUIC不是TCP的替代品
    CPU 飙高问题排查和解决方法
    二、vue2脚手架-组件化开发
    MP3是如何诞生的?
    如何在三维地球上加载obj、fbx、ifc、dae、3ds、gltf/glb模型?
    【Linux】 - Linux中的重定向和管道符
  • 原文地址:https://www.cnblogs.com/willian/p/17490901.html
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号