在网上看到一个bezier曲线的公式,那就用Maya的节点来实现下,看看效果,具体公式如下图:
这个是二维的,三维的化再加个z轴向就行,
import maya.OpenMayaMPx as OpenMayaMPx
import maya.OpenMaya as OpenMaya
class BezierCubic(OpenMayaMPx.MPxNode):
kPluginNodeId = OpenMaya.MTypeId(0x00000121)
aP1 = OpenMaya.MObject()
aP2 = OpenMaya.MObject()
aP3 = OpenMaya.MObject()
aP4 = OpenMaya.MObject()
aSum = OpenMaya.MObject()
aBias = OpenMaya.MObject()
def __init__(self):
OpenMayaMPx.MPxNode.__init__(self)
def compute(self, plug, data):
p1 = data.inputValue(BezierCubic.aP1).asVector()
p2 = data.inputValue(BezierCubic.aP2).asVector()
p3 = data.inputValue(BezierCubic.aP3).asVector()
p4 = data.inputValue(BezierCubic.aP4).asVector()
t = data.inputValue(BezierCubic.aBias).asFloat()
sum = p1 * pow(1 - t, 3) + p2 * 3 * t * pow(1 - t, 2) + p3 * 3 * pow(t, 2) * (1 - t) + p4 * pow(t, 3)
outputData = data.outputValue(BezierCubic.aSum)
outputData.set3Double(sum[0], sum[1], sum[2])
data.setClean(plug)
def creator():
return OpenMayaMPx.asMPxPtr(BezierCubic())
def initialize():
nAttr = OpenMaya.MFnNumericAttribute()
BezierCubic.aP1 = nAttr.create('Point1', 'p1', OpenMaya.MFnNumericData.k3Double)
BezierCubic.addAttribute(BezierCubic.aP1)
BezierCubic.aP2 = nAttr.create('Point2', 'p2', OpenMaya.MFnNumericData.k3Double)
BezierCubic.addAttribute(BezierCubic.aP2)
BezierCubic.aP3 = nAttr.create('Point3', 'p3', OpenMaya.MFnNumericData.k3Double)
BezierCubic.addAttribute(BezierCubic.aP3)
BezierCubic.aP4 = nAttr.create('Point4', 'p4', OpenMaya.MFnNumericData.k3Double)
BezierCubic.addAttribute(BezierCubic.aP4)
BezierCubic.aSum = nAttr.create('SumBezier', 'sum', OpenMaya.MFnNumericData.k3Double)
nAttr.setWritable(True)
BezierCubic.addAttribute(BezierCubic.aSum)
BezierCubic.aBias = nAttr.create('Bias', 't', OpenMaya.MFnNumericData.kFloat, 0.0)
nAttr.setSoftMin = 0.0
nAttr.setSoftMax = 1.0
nAttr.setKeyable(True)
nAttr.setWritable(True)
BezierCubic.addAttribute(BezierCubic.aBias)
BezierCubic.attributeAffects(BezierCubic.aBias, BezierCubic.aSum)
BezierCubic.attributeAffects(BezierCubic.aP1, BezierCubic.aSum)
BezierCubic.attributeAffects(BezierCubic.aP2, BezierCubic.aSum)
BezierCubic.attributeAffects(BezierCubic.aP3, BezierCubic.aSum)
BezierCubic.attributeAffects(BezierCubic.aP4, BezierCubic.aSum)
def initializePlugin(obj):
plugin = OpenMayaMPx.MFnPlugin(obj, 'Chuck', '1.0', 'Bezier')
try:
plugin.registerNode('BezierCubic', BezierCubic.kPluginNodeId, creator, initialize)
except:
raise RuntimeError('Failed to register node')
def uninitializePlugin(obj):
plugin = OpenMayaMPx.MFnPlugin(obj)
try:
plugin.deregisterNode(BezierCubic.kPluginNodeId)
except:
raise RuntimeError('Failed to unregister node')
核心的代码就这一句
sum = p1 * pow(1 - t, 3) + p2 * 3 * t * pow(1 - t, 2) + p3 * 3 * pow(t, 2) * (1 - t) + p4 * pow(t, 3)
t为小球在Bezier曲线上的位置,这里设置为1到0,也就是从起始位置到结束位置。
在Maya里挂载下就可以执行我们的操作了
import maya.cmds as cmds
from math import *
l1 = cmds.spaceLocator(n='loc1')
cmds.xform(l1, t=(-6, 0, -2), ws=1)
l2 = cmds.spaceLocator(n='loc2')
cmds.xform(l2, t=(-5, 0, -6), ws=1)
l3 = cmds.spaceLocator(n='loc3')
cmds.xform(l3, t=(1, 0, -6), ws=1)
l4 = cmds.spaceLocator(n='loc4')
cmds.xform(l4, t=(2, 0, -2), ws=1)
for i in range(0, 11):
node_name = 'BezierCubic' + str(i)
sphere_name = 'sphere' + str(i)
sphere = cmds.sphere(n=sphere_name, r=.5)
cmds.createNode('BezierCubic', n=node_name)
cmds.connectAttr('loc1.translate', node_name + '.Point1')
cmds.connectAttr('loc2.translate', node_name + '.Point2')
cmds.connectAttr('loc3.translate', node_name + '.Point3')
cmds.connectAttr('loc4.translate', node_name + '.Point4')
cmds.connectAttr(node_name + '.SumBezier', sphere_name + '.translate')
cmds.setAttr(node_name + '.Bias', i / 1.0 * 0.1)
这是最后的实际效果
来源:CSDN
作者:lulongfei172006
链接:https://blog.csdn.net/lulongfei172006/article/details/104860812