ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 09 Jun 2021 23:09:03 +0200Problem with plotting a 3d Bezier curvehttps://ask.sagemath.org/question/56590/problem-with-plotting-a-3d-bezier-curve/ I have a problem with plotting a Bezier spline in 3d.
In 2d this simply works:
p2d = [[(3.0,0.0),(3.0,0.13),(2.94,0.25),(2.8,0.35)],
[(2.7,0.44),(2.6,0.5),(2.5,0.5)],
[(2.36,0.5),(2.24,0.44),(2.14,0.35)],
[(2.05,0.25),(2.0,0.13),(2.0,6.1e-17)]]
bezier_path(p2d)
But when I want to plot it in 3d, this line
bezier_path(p2d).plot3d()
or
p3d = [[(3.0,0.0,0.0),(3.0,0.13,0.0),(2.94,0.25,0.0),(2.8,0.35,0.0)],
[(2.7,0.44,0.0),(2.6,0.5,0.0),(2.5,0.5,0.0)],
[(2.36,0.5,0.0),(2.24,0.44,0.0),(2.14,0.35,0.0)],
[(2.05,0.25,0.0),(2.0,0.13,0.0),(2.0,6.1e-17,0.0)]]
bezier3d(p3d)
both give me the following error: TypeError: unable to convert -(t - 1)^3 to an integer.
What am I doing wrong?Sat, 10 Apr 2021 09:12:55 +0200https://ask.sagemath.org/question/56590/problem-with-plotting-a-3d-bezier-curve/Answer by vdelecroix for <p>I have a problem with plotting a Bezier spline in 3d.</p>
<p>In 2d this simply works:</p>
<pre><code>p2d = [[(3.0,0.0),(3.0,0.13),(2.94,0.25),(2.8,0.35)],
[(2.7,0.44),(2.6,0.5),(2.5,0.5)],
[(2.36,0.5),(2.24,0.44),(2.14,0.35)],
[(2.05,0.25),(2.0,0.13),(2.0,6.1e-17)]]
bezier_path(p2d)
</code></pre>
<p>But when I want to plot it in 3d, this line </p>
<pre><code>bezier_path(p2d).plot3d()
</code></pre>
<p>or</p>
<pre><code>p3d = [[(3.0,0.0,0.0),(3.0,0.13,0.0),(2.94,0.25,0.0),(2.8,0.35,0.0)],
[(2.7,0.44,0.0),(2.6,0.5,0.0),(2.5,0.5,0.0)],
[(2.36,0.5,0.0),(2.24,0.44,0.0),(2.14,0.35,0.0)],
[(2.05,0.25,0.0),(2.0,0.13,0.0),(2.0,6.1e-17,0.0)]]
bezier3d(p3d)
</code></pre>
<p>both give me the following error: TypeError: unable to convert -(t - 1)^3 to an integer.</p>
<p>What am I doing wrong?</p>
https://ask.sagemath.org/question/56590/problem-with-plotting-a-3d-bezier-curve/?answer=56597#post-id-56597This looks like a bug and I opened the ticket [#31640](https://trac.sagemath.org/ticket/31640) to track the issue. Thanks for your report!
The issue turns out to be a missing vector conversion in the code. I posted a fix and should hopefully make it for a later release.
As a work around you can use the following function (that contains the fix I provided in the ticket)
def bezier3d(path, **options):
from . import parametric_plot3d as P3D
from sage.modules.free_module_element import vector
from sage.symbolic.ring import SR
p0 = vector(path[0][-1])
t = SR.var('t')
if len(path[0]) > 2:
B = (1-t)**3*vector(path[0][0])+3*t*(1-t)**2*vector(path[0][1])+3*t**2*(1-t)*vector(path[0][-2])+t**3*p0
G = P3D.parametric_plot3d(list(B), (0, 1), **options)
else:
G = line3d([path[0][0], p0], **options)
for curve in path[1:]:
if len(curve) > 1:
p1 = vector(curve[0])
p2 = vector(curve[-2])
p3 = vector(curve[-1])
B = (1-t)**3*p0+3*t*(1-t)**2*p1+3*t**2*(1-t)*p2+t**3*p3
G += P3D.parametric_plot3d(list(B), (0, 1), **options)
else:
G += line3d([p0,curve[0]], **options)
p0 = vector(curve[-1]) # this was the wrong line!
return GSat, 10 Apr 2021 19:30:42 +0200https://ask.sagemath.org/question/56590/problem-with-plotting-a-3d-bezier-curve/?answer=56597#post-id-56597Comment by vdelecroix for <p>This looks like a bug and I opened the ticket <a href="https://trac.sagemath.org/ticket/31640">#31640</a> to track the issue. Thanks for your report!</p>
<p>The issue turns out to be a missing vector conversion in the code. I posted a fix and should hopefully make it for a later release.</p>
<p>As a work around you can use the following function (that contains the fix I provided in the ticket)</p>
<pre><code>def bezier3d(path, **options):
from . import parametric_plot3d as P3D
from sage.modules.free_module_element import vector
from sage.symbolic.ring import SR
p0 = vector(path[0][-1])
t = SR.var('t')
if len(path[0]) > 2:
B = (1-t)**3*vector(path[0][0])+3*t*(1-t)**2*vector(path[0][1])+3*t**2*(1-t)*vector(path[0][-2])+t**3*p0
G = P3D.parametric_plot3d(list(B), (0, 1), **options)
else:
G = line3d([path[0][0], p0], **options)
for curve in path[1:]:
if len(curve) > 1:
p1 = vector(curve[0])
p2 = vector(curve[-2])
p3 = vector(curve[-1])
B = (1-t)**3*p0+3*t*(1-t)**2*p1+3*t**2*(1-t)*p2+t**3*p3
G += P3D.parametric_plot3d(list(B), (0, 1), **options)
else:
G += line3d([p0,curve[0]], **options)
p0 = vector(curve[-1]) # this was the wrong line!
return G
</code></pre>
https://ask.sagemath.org/question/56590/problem-with-plotting-a-3d-bezier-curve/?comment=57516#post-id-57516The fix is incorporated in sage 9.3!Wed, 09 Jun 2021 23:09:03 +0200https://ask.sagemath.org/question/56590/problem-with-plotting-a-3d-bezier-curve/?comment=57516#post-id-57516