【maya插件】用曲线生成谢尔宾斯基三角(分形)

需求

写一个maya插(wǎn)件(jv),生成如下分形
在这里插入图片描述

实现

通过维基百科,我们知道Sierpinski triangle有许多种生成方式。

其中L系统生成法仅用一条曲线:

变数:A , B
常数:+ , -
公理:A
规则:A → B-A-B, B → A+B+A

  • A, B : 向前
  • - : 左转60°
  • + : 右转60°

我的理解:

L系统生成的谢尔宾斯基三角就是一条曲线。初始时,我们叫它A,一条向前(在我的代码中,角度为0的向前=向右)的曲线。
迭代1次的结果

经过2次迭代,曲线A变成+B-A-B,也就是一条+60°、向前延申、-60°、向前、-60°、向前的曲线BAB。
迭代2次的结果
经过3次迭代,曲线BAB变成曲线ABA BAB ABA,其中B变成-A+B+A,也就是一条-60°、向前延申、+60°、向前、+60°、向前的曲线。

迭代3次的结果
迭代次数越多,三角越成型,速度越慢(控制点以3n+1的数量级增长)。

迭代10次的结果

from maya import cmds
import math
from PySide2 import QtWidgets

def get_points(length = 1, depth = 1):
    points = [[0,0,0]]
    points += get_points_sub('A', points[0], length, 0, depth)
    return points

def get_points_sub(state, beginPosition, length, angle, depth):
    if depth == 1:
        # print state, beginPosition, length, angle, depth
        point = [beginPosition[0] + length * math.cos(math.radians(angle)), 
                 beginPosition[1] + length * math.sin(math.radians(angle)), 
                 0]
        return [point]
        
    if state == 'A':
        angle += 60
        p1 = get_points_sub('B', beginPosition, length/2, angle, depth-1)
        angle -= 60
        p2 = get_points_sub('A', p1[-1], length/2, angle, depth-1)
        angle -= 60
        p3 = get_points_sub('B', p2[-1], length/2, angle, depth-1)
    elif state == 'B':
        angle -= 60
        p1 = get_points_sub('A', beginPosition, length/2, angle, depth-1)
        angle += 60
        p2 = get_points_sub('B', p1[-1], length/2, angle, depth-1)
        angle += 60
        p3 = get_points_sub('A', p2[-1], length/2, angle, depth-1)
    points = p1 + p2 + p3
    return points

class Fractal(QtWidgets.QWidget):

    def __init__(self, parent=None):
        super(Fractal, self).__init__(parent)
        self.create_ui()
        
    def create_ui(self):
        self.resize(400, 150)
        self.setWindowTitle("Fractal")

        # length
        length_label = QtWidgets.QLabel()
        length_label.setText("length")

        self.length = QtWidgets.QDoubleSpinBox()
        self.length.setRange(0.0, 1000.0)
        self.length.setSingleStep(10)
        self.length.setValue(1.0)

        length_layout = QtWidgets.QHBoxLayout()
        length_layout.addWidget(length_label)
        length_layout.addWidget(self.length)

        # depth
        depth_label = QtWidgets.QLabel()
        depth_label.setText("depth(<=10)")

        self.depth = QtWidgets.QSpinBox()
        self.depth = QtWidgets.QSpinBox()
        self.depth.setRange(0, 10)
        self.depth.setSingleStep(1)
        self.depth.setValue(1)

        depth_layout = QtWidgets.QHBoxLayout()
        depth_layout.addWidget(depth_label)
        depth_layout.addWidget(self.depth)

        # layout
        button = QtWidgets.QPushButton("Generate", self)
        button.clicked.connect(self.generate)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(length_layout)
        layout.addLayout(depth_layout)
        layout.addWidget(button)
        self.setLayout(layout)
    
    def generate(self):
        length = self.length.value()
        depth = self.depth.value()
        points = get_points(length, depth)
        # print points
        curve = cmds.curve(d=1, p=points)
        cmds.select(curve)

if __name__ == '__main__':
    fractal = Fractal()
    fractal.show()

怎么运行

  1. 首先你需要安装maya。理论上任何一个版本都行,我用的是maya 2018。

  2. 打开“脚本编辑器”面板
    在这里插入图片描述

  3. 创建一个运行python脚本的窗口
    在这里插入图片描述

  4. 拷贝本文的代码进去,点击运行
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值