对于VMobject的深入研究
首先,VMobject是由anchors和handles实现的贝塞尔曲线,例如:
View Code
def playscene0(): plane = NumberPlane() vmobject = VMobject(color=GREEN) vmobject.points = [ np.array([-3, 0, 0]), np.array([-3, 2, 0]), np.array([-2, 3, 0]), np.array([0, 3, 0]), np.array([0, 3, 0]), np.array([2, 3, 0]), np.array([3, 2, 0]), np.array([3, 0, 0]), ] sa(plane, vmobject);sw()
其次,我们来考察一下内置的VMobject:
def playscene0(): c = Text('C')[0] # 注意要加索引,否则为空数组 li = c.get_anchors_and_handles() print(li)
结果为:

[array([[ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17], [-6.63085750e-02, -2.25390650e-01, 2.76023938e-17], [-1.33496075e-01, -1.78320300e-01, 2.18379385e-17], [-1.79785175e-01, -1.03515650e-01, 1.26770109e-17], [-1.96972675e-01, -4.10155000e-03, 5.02295008e-19], [-1.80175775e-01, 9.64843500e-02, -1.18159250e-17], [-1.33300775e-01, 1.74023450e-01, -2.13117261e-17], [-6.33788750e-02, 2.24023450e-01, -2.74349601e-17], [ 2.29492250e-02, 2.41601550e-01, -2.95876565e-17], [ 8.46679750e-02, 2.33007800e-01, -2.85352256e-17], [ 1.37402325e-01, 2.09375000e-01, -2.56410424e-17], [ 1.50683625e-01, 2.31445300e-01, -2.83438746e-17], [ 1.76660175e-01, 2.31445300e-01, -2.83438746e-17], [ 1.79589825e-01, 6.67968500e-02, -8.18025485e-18], [ 1.53027325e-01, 6.67968500e-02, -8.18025485e-18], [ 1.37207025e-01, 1.18945300e-01, -1.45665981e-17], [ 1.12988275e-01, 1.66601550e-01, -2.04028055e-17], [ 7.58789250e-02, 2.01367200e-01, -2.46603697e-17], [ 2.68554750e-02, 2.13867200e-01, -2.61911782e-17], [-3.19335750e-02, 1.99804700e-01, -2.44690186e-17], [-7.88085750e-02, 1.58398450e-01, -1.93982155e-17], [-1.08496075e-01, 9.12109500e-02, -1.11701198e-17], [-1.19238275e-01, 3.90650000e-04, -4.78408272e-20], [-1.08105475e-01, -8.08593500e-02, 9.90241442e-18], [-7.58788750e-02, -1.45703150e-01, 1.78434896e-17], [-2.66601750e-02, -1.89062500e-01, 2.31534785e-17], [ 3.68164250e-02, -2.04687500e-01, 2.50669892e-17], [ 8.52539250e-02, -1.96484350e-01, 2.40623930e-17], [ 1.23730475e-01, -1.74414050e-01, 2.13595608e-17], [ 1.52246125e-01, -1.41992200e-01, 1.73890293e-17], [ 1.72558625e-01, -1.02148450e-01, 1.25095772e-17], [ 1.96972675e-01, -1.13867200e-01, 1.39447102e-17], [ 1.22753925e-01, -2.12109350e-01, 2.59759037e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17]]), array([[-1.47460750e-02, -2.41601550e-01, 2.95876565e-17], [-9.16992250e-02, -2.14648450e-01, 2.62868537e-17], [-1.53027325e-01, -1.58007800e-01, 1.93503747e-17], [-1.91503875e-01, -7.42187500e-02, 9.08917546e-18], [-1.97167975e-01, 3.28125000e-02, -4.01837231e-18], [-1.68847675e-01, 1.26562500e-01, -1.54994361e-17], [-1.13574225e-01, 1.95507800e-01, -2.39428001e-17], [-3.66210750e-02, 2.35546850e-01, -2.88461696e-17], [ 4.54101750e-02, 2.41406250e-01, -2.95637391e-17], [ 1.03027325e-01, 2.27343750e-01, -2.78415796e-17], [ 1.41829425e-01, 2.16731767e-01, -2.65419864e-17], [ 1.59342475e-01, 2.31445300e-01, -2.83438746e-17], [ 1.77636725e-01, 1.76562483e-01, -2.16226680e-17], [ 1.70735658e-01, 6.67968500e-02, -8.18025485e-18], [ 1.49316425e-01, 8.26172000e-02, -1.01176890e-17], [ 1.30175775e-01, 1.37500000e-01, -1.68388935e-17], [ 1.02441425e-01, 1.81250000e-01, -2.21967232e-17], [ 6.14257750e-02, 2.09570300e-01, -2.56649597e-17], [ 5.56642500e-03, 2.13671850e-01, -2.61672547e-17], [-5.00976750e-02, 1.90429700e-01, -2.33209123e-17], [-9.15038750e-02, 1.40625000e-01, -1.72215956e-17], [-1.15722675e-01, 6.40625000e-02, -7.84539356e-18], [-1.19238275e-01, -2.91015500e-02, 3.56391201e-18], [-1.00683575e-01, -1.05664050e-01, 1.29401141e-17], [-6.22070250e-02, -1.64453150e-01, 2.01397024e-17], [-7.71482500e-03, -1.99609350e-01, 2.44450952e-17], [ 5.41992250e-02, -2.04687500e-01, 2.50669892e-17], [ 1.00097675e-01, -1.91015650e-01, 2.33926704e-17], [ 1.34277325e-01, -1.65039050e-01, 2.02114544e-17], [ 1.60449225e-01, -1.29882800e-01, 1.59060555e-17], [ 1.80696642e-01, -1.06054700e-01, 1.29879549e-17], [ 1.78027325e-01, -1.59765650e-01, 1.95656492e-17], [ 9.18945250e-02, -2.31835940e-01, 2.83917142e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17]]), array([[-4.11132750e-02, -2.36328150e-01, 2.89418512e-17], [-1.14160175e-01, -1.98828150e-01, 2.43494257e-17], [-1.68457025e-01, -1.33203150e-01, 1.63126811e-17], [-1.97167975e-01, -4.10156500e-02, 5.02296845e-18], [-1.91503875e-01, 6.64062500e-02, -8.13242015e-18], [-1.53222675e-01, 1.52343750e-01, -1.86567286e-17], [-9.03320250e-02, 2.12109350e-01, -2.59759037e-17], [-7.91017500e-03, 2.41406250e-01, -2.95637391e-17], [ 6.61132750e-02, 2.38671850e-01, -2.92288717e-17], [ 1.20605475e-01, 2.19335950e-01, -2.68609069e-17], [ 1.46256525e-01, 2.24088533e-01, -2.74429305e-17], [ 1.68001325e-01, 2.31445300e-01, -2.83438746e-17], [ 1.78613275e-01, 1.21679667e-01, -1.49014614e-17], [ 1.61881492e-01, 6.67968500e-02, -8.18025485e-18], [ 1.44042975e-01, 1.00000000e-01, -1.22464680e-17], [ 1.22167975e-01, 1.53320300e-01, -1.87763215e-17], [ 9.01367250e-02, 1.92968750e-01, -2.36318562e-17], [ 4.50195250e-02, 2.13671850e-01, -2.61672547e-17], [-1.39648250e-02, 2.08984350e-01, -2.55932015e-17], [-6.57226750e-02, 1.76562500e-01, -2.16226700e-17], [-1.01464825e-01, 1.18359350e-01, -1.44948399e-17], [-1.19238275e-01, 3.37890500e-02, -4.13796519e-18], [-1.15527325e-01, -5.62500000e-02, 6.88863825e-18], [-8.99413750e-02, -1.27343750e-01, 1.55951116e-17], [-4.58007750e-02, -1.78906250e-01, 2.19096966e-17], [ 1.33789250e-02, -2.04687500e-01, 2.50669892e-17], [ 7.04101750e-02, -2.01953150e-01, 2.47321279e-17], [ 1.12792975e-01, -1.83789050e-01, 2.25076672e-17], [ 1.43847675e-01, -1.54101550e-01, 1.88719970e-17], [ 1.67285175e-01, -1.16601550e-01, 1.42795715e-17], [ 1.88834658e-01, -1.09960950e-01, 1.34663325e-17], [ 1.53417975e-01, -1.92578150e-01, 2.35840215e-17], [ 5.51757750e-02, -2.41601550e-01, 2.95876565e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17]]), array([[-6.63085750e-02, -2.25390650e-01, 2.76023938e-17], [-1.33496075e-01, -1.78320300e-01, 2.18379385e-17], [-1.79785175e-01, -1.03515650e-01, 1.26770109e-17], [-1.96972675e-01, -4.10155000e-03, 5.02295008e-19], [-1.80175775e-01, 9.64843500e-02, -1.18159250e-17], [-1.33300775e-01, 1.74023450e-01, -2.13117261e-17], [-6.33788750e-02, 2.24023450e-01, -2.74349601e-17], [ 2.29492250e-02, 2.41601550e-01, -2.95876565e-17], [ 8.46679750e-02, 2.33007800e-01, -2.85352256e-17], [ 1.37402325e-01, 2.09375000e-01, -2.56410424e-17], [ 1.50683625e-01, 2.31445300e-01, -2.83438746e-17], [ 1.76660175e-01, 2.31445300e-01, -2.83438746e-17], [ 1.79589825e-01, 6.67968500e-02, -8.18025485e-18], [ 1.53027325e-01, 6.67968500e-02, -8.18025485e-18], [ 1.37207025e-01, 1.18945300e-01, -1.45665981e-17], [ 1.12988275e-01, 1.66601550e-01, -2.04028055e-17], [ 7.58789250e-02, 2.01367200e-01, -2.46603697e-17], [ 2.68554750e-02, 2.13867200e-01, -2.61911782e-17], [-3.19335750e-02, 1.99804700e-01, -2.44690186e-17], [-7.88085750e-02, 1.58398450e-01, -1.93982155e-17], [-1.08496075e-01, 9.12109500e-02, -1.11701198e-17], [-1.19238275e-01, 3.90650000e-04, -4.78408272e-20], [-1.08105475e-01, -8.08593500e-02, 9.90241442e-18], [-7.58788750e-02, -1.45703150e-01, 1.78434896e-17], [-2.66601750e-02, -1.89062500e-01, 2.31534785e-17], [ 3.68164250e-02, -2.04687500e-01, 2.50669892e-17], [ 8.52539250e-02, -1.96484350e-01, 2.40623930e-17], [ 1.23730475e-01, -1.74414050e-01, 2.13595608e-17], [ 1.52246125e-01, -1.41992200e-01, 1.73890293e-17], [ 1.72558625e-01, -1.02148450e-01, 1.25095772e-17], [ 1.96972675e-01, -1.13867200e-01, 1.39447102e-17], [ 1.22753925e-01, -2.12109350e-01, 2.59759037e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17], [ 1.27929750e-02, -2.41601550e-01, 2.95876565e-17]])]
于是我尝试通过anchors和handles来实现自定义的VMobject,以正方形为例:
c = Square() li = c.get_anchors_and_handles() # 获取VMobject的anchors和handles l = len(li[0]) # 注意li的长度为4,这意味这[li[0][i],li[1][i],li[2][i],li[3][i]]组成一条贝塞尔曲线 v = VMobject() # 创建空的VMobject myli = [] for i in range(l): myli.append(li[0][i]);myli.append(li[1][i]);myli.append(li[2][i]);myli.append(li[3][i]) # 注意不需要加[] v.points = myli sa(v);sw()
如果将c改为Text也可以实现(注意要加索引)
注意这样产生的VMobject仅仅是一个轮廓,即DrawBorderThenFill().get_outline(),我们可以通过更改VMobject的属性:
v = VMobject(stroke_width=10, fill_color=BLUE, fill_opacity=1)
注意观察stroke_width的含义,例如,对正方形来说,我们并没有绘制内外两条贝塞尔曲线,只是绘制了一条曲线(四条边,而不是八条边):
[array([1., 1., 0.]), array([0.33333333, 1., 0.]), array([-0.33333333, 1., 0.]), array([-1., 1., 0.]), array([-1., 1., 0.]), array([-1., 0.33333333, 0.]), array([-1., -0.33333333, 0.]), array([-1., -1., 0.]), array([-1., -1., 0.]), array([-0.33333333, -1., 0.]), array([ 0.33333333, -1., 0.]), array([ 1., -1., 0.]), array([ 1., -1., 0.]), array([ 1., -0.33333333, 0.]), array([1., 0.33333333, 0.]), array([1., 1., 0.])]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)