如何在 maxscript 中使用海龟图形来对齐弯曲的盒子

Posted

技术标签:

【中文标题】如何在 maxscript 中使用海龟图形来对齐弯曲的盒子【英文标题】:How can I use turtle graphics in maxscript to align the bent boxes 【发布时间】:2020-10-18 23:46:25 【问题描述】:
struct Turtle (

    position_ = [0, 0, 0], 
    heading_= [0, 1, 0], 
    rotationQuat_ = quat 0 0 0 1,
    amount = 200,
    turnAngle = 45,

    fn forward = (      
        c = box pos: position_ wirecolor: red width: 40 length: amount height: 2 lengthSegs: 10
        rotate c rotationQuat_
        position_ = position_ + amount * heading_
    ),
    fn left = (
        q = quat -turnAngle [0, 0, 1]
        rotationQuat_ = q * rotationQuat_
        invq = inverse q           
        heading_ = heading_ * invq  

        c = box pos: position_ wirecolor: red width: 40 length: amount height: 2 lengthSegs: 10
        addmodifier c (bend())
        c.bend.bendAngle = 45
        c.bend.bendAxis = 1     
            
        rotate c rotationQuat_
        position_ = position_ + amount * heading_
    ),
    fn right = (
        q = quat turnAngle [0, 0, 1] 
        rotationQuat_ = q * rotationQuat_ 
        invq = inverse q               
        heading_ = heading_ * invq  

        c = box pos: position_ wirecolor: red width: 40 length: amount height: 2 lengthSegs: 10
        addmodifier c (bend())
        c.bend.bendangle = -45
        c.bend.bendAxis = 1
            
        rotate c rotationQuat_
        position_ = position_ + amount * heading_
    )
)

fn main = (
    delete objects
    
    t = Turtle()

    t.left()
    t.left()
    t.left()
    t.left()
    t.left()
    t.left()
    t.left()
    t.right()
    t.forward()
    t.forward()
    t.right()
    
)

main()

我正在尝试使用海龟图形创建一条路径,但是因为一旦弯曲盒子就无法正确对齐,我无法让它们对齐。我设法通过更改每个形状的枢轴点使其暂时工作,但它是硬编码的,因此只能在某些情况下工作。如何让每个框对齐?

【问题讨论】:

【参考方案1】:

我会利用盒子的枢轴在局部 Z 为零的事实,并切换盒子和弯曲 Gizmo 的方向,使其围绕其底部而不是围绕中心弯曲。由于您正在弯曲盒子,因此您也不能简单地按盒子长度移动,而是必须计算沿弯曲弧线的偏移量。总而言之,我就是这样做的:

struct Turtle
(
    private transform = arbAxis y_axis,
    public stepLength = 200,
    public turnAngle = 45,

    private fn updateTransform angle distance =
        if angle == 0 then transform *= transMatrix (transform.row3 * distance)
        else transform = rotateYMatrix angle * transMatrix (distance / degToRad angle * [1 - cos angle, 0, sin angle]) * transform,

    private fn stride distance bendAngle =
    (
        local stripe = Box width:40 length:2 height:stepLength widthSegs:1 lengthSegs:1 heightSegs:10 transform:transform wirecolor:red
        if bendAngle != 0 do addModifier stripe (Bend bendAxis:2 bendAngle:bendAngle)
        updateTransform bendAngle distance
    ),
    
    public fn forward = stride stepLength 0,
    public fn left = stride stepLength turnAngle,
    public fn right = stride stepLength -turnAngle
)

【讨论】:

这是一个很好的答案,但是说我想在形状的外部/内部放置一些东西我将如何更改代码?如果我添加的对象与形状有相对位置。您能解释一下您在 updateTransform() 函数中所做的矩阵数学运算吗? 您可以按照放置盒子的方式进行操作-但这样说这是一个不同的问题,也可能有不同的答案-您自己提到了一个“形状”不是弯曲的盒子真正是什么(恕我直言,你最好做一条指导线)。矩阵数学是 1)按增量旋转,2)沿弧偏移(距离/弧度角为您提供弧的半径,cos 和 sin 为您提供沿 x 移动一个单位的单位圆上的点(你已经在弧上),因此减去 1),3)乘以最后一次变换。

以上是关于如何在 maxscript 中使用海龟图形来对齐弯曲的盒子的主要内容,如果未能解决你的问题,请参考以下文章

python海龟画图怎么把背景变成黑色

使用海龟图形和递归的希尔伯特曲线

我想在Python中加入海龟图形的功能。

如何在 Python 中隐藏海龟图标/指针

Python海龟窗口执行完代码后如何关闭它?

将 Python 海龟图形保存为动画 .gif?