英文:
Error in manim TypeError: LinearGradient.__new__() takes exactly 4 arguments (2 given)
问题
问题显然出现在定义抛物面(paraboloid)的Surface部分,你错在哪里了?错误信息是:
TypeError: LinearGradient.new() 接受正好 4 个参数(给定了 2 个)。
似乎在定义表面时缺少一些参数。看起来 LinearGradient 方法位于 Surface 类内部。
要解决这个问题,你需要查看 Surface 类的文档,确保正确地传递参数。在你的代码中,你正在尝试通过填充颜色(fill_color)和渐变颜色(checkerboard_colors)来定义表面的外观。根据错误信息,似乎你需要传递 LinearGradient 方法所需的正确参数。
请查阅 Manim 文档或 Surface 类的源代码,以确定正确的参数传递方式,并相应地更新你的代码以解决这个问题。
英文:
from manim import *
class Solids(ThreeDScene):
def construct(self):
x_min, x_max, x_step = 0, 5, 1
y_min, y_max, y_step = -5, 5, 1
z_max, z_min, z_step = -5, 5, 1
axes = ThreeDAxes(
x_range=[x_min, x_max + x_step, x_step],
y_range=[y_min, y_max + y_step, y_step],
z_range=[z_min, z_max + z_step, z_step],)
function = axes.plot(lambda x: np.sqrt(
x), color=YELLOW, x_range=[0, 5])
area = axes.get_area(function, x_range=[0, 5], color=BLUE)
rec = axes.get_riemann_rectangles(function, dx=0.2, x_range=[
1, 1.2], input_sample_type="left", stroke_width=0.5, fill_opacity=0.75, color=BLUE)
rec_label = Text("dx", font_size=20)
rec_label.next_to(rec, DOWN, buff=0,)
group = VGroup(function, area, rec)
# parametric surface of sqrt of x but in 3d roatetd about x axis
def funcs(u, v):
return np.array([
np.sqrt((u)-(v**2)),
u
])
start_color = BLUE
end_color = YELLOW
paraboloid = Surface(
lambda u, v: axes.c2p(*funcs(u, v)), u_range=[0, 5], v_range=[-5, 5], fill_color=end_color,
color=start_color, resolution=8, checkerboard_colors=[start_color, end_color], fill_opacity=0.75, stroke_color=BLUE, stroke_width=0.5,)
self.play(FadeIn(axes))
self.wait(2)
self.play(FadeIn(function))
self.play(FadeIn(rec))
self.play(Write(rec_label))
self.play(FadeIn(area))
self.wait(2)
self.begin_ambient_camera_rotation()
self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES)
self.play(Rotating(group, axis=RIGHT, radians=2*PI,
about_point=ORIGIN), run_time=5, rate_func=linear)
self.wait(2)
self.play(FadeIn(paraboloid))
self.wait(2)
the problem is clearly in defining paraboloid Surface what did I get wrong? error:
TypeError: LinearGradient.new() takes exactly 4 arguments (2 given)
seems like I am missing some args when defining the surface. seems like the LinearGradient method is inside the Surface class
答案1
得分: 1
以下是代码的翻译部分:
存在于您的`Surface()`对象中的两个问题:
a) 要绘制的函数需要返回三个值,即x、y和z值,以覆盖该表面。
b) 您的函数至少在某些点上返回复数,因为`np.sqrt((u)-v**2)`的参数小于零。
我删除了其他所有内容,只保留了`Surface()`的最简版本。我不知道这是否符合您的期望,但至少这段代码可以正常运行。
接下来是两个编辑后的版本,一个是在柱坐标系中参数化表面,另一个是在x/y平面上映射u和v,但需要限制y的范围以避免复数值。
英文:
There are 2 problems in your Surface()
object:
a) the function to be plotted needs to return 3 values, the x, y and z value to span the surface
b) your function at least at some points delivers complex numbers as a result of the argument of np.sqrt((u)-v**2)
becoming less than zero
I cut out everything else and made a minimalistic version of just the Surface()
I don't know if this is what you expect to see, but at least the code runs without error.
class SolidsMini(ThreeDScene):
def construct(self):
x_min, x_max, x_step = 0, 5, 1
y_min, y_max, y_step = -5, 5, 1
z_max, z_min, z_step = -5, 5, 1
axes = ThreeDAxes(
x_range=[x_min, x_max + x_step, x_step],
y_range=[y_min, y_max + y_step, y_step],
z_range=[z_min, z_max + z_step, z_step],)
def funcs(u, v):
return np.array([
u, v, np.sqrt(abs((u)-(v**2))),
])
start_color = BLUE
end_color = YELLOW
paraboloid = Surface(
lambda u, v: axes.c2p(*funcs(u, v)),
u_range=[0, 5],
v_range=[-5, 5],
#fill_color=end_color,
#color=start_color,
resolution=8,
checkerboard_colors=[start_color, end_color],
fill_opacity=0.75,
stroke_color=BLUE,
stroke_width=0.5,
)
self.play(FadeIn(axes))
self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES)
self.wait(2)
self.play(FadeIn(paraboloid))
self.wait(2)
Edit 2023-06-14
Ok, with this new information: The easiest way would be to parametrize your surface in cylindrical coordinates then:
def construct(self):
x_min, x_max, x_step = -5, 5, 1
y_min, y_max, y_step = -5, 5, 1
z_min, z_max, z_step = -5, 5, 1
axes = ThreeDAxes(
x_range=[x_min, x_max + x_step, x_step],
y_range=[y_min, y_max + y_step, y_step],
z_range=[z_min, z_max + z_step, z_step],
)
def funcs(u, v):
# parametrize u as x and v as phi
# then the radius increases as the sqrt(u)
return [u, np.sqrt(u)*np.cos(v), np.sqrt(u)*np.sin(v)]
start_color = BLUE
end_color = YELLOW
paraboloid = Surface(
lambda u, v: axes.c2p(*funcs(u, v)),
u_range=[0.01, 5],
v_range=[0, 2*PI],
resolution=20,
checkerboard_colors=[start_color, end_color],
fill_opacity=0.75,
stroke_color=BLUE,
stroke_width=0.5,
)
self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES)
self.add(axes)
self.add(paraboloid)
self.wait()
Alternatively you can map u and v onto the x/y plane but y needs to be limited since python will happily draw the root out of a negative number and return a complex value....
class SolidsMini2(ThreeDScene):
def construct(self):
x_min, x_max, x_step = -5, 5, 1
y_min, y_max, y_step = -5, 5, 1
z_min, z_max, z_step = -5, 5, 1
axes = ThreeDAxes(
x_range=[x_min, x_max + x_step, x_step],
y_range=[y_min, y_max + y_step, y_step],
z_range=[z_min, z_max + z_step, z_step],
)
def upper(u, v):
# parametrize u as x and v as y
# y needs to be limited
# -np.sqrt(u) <= y <= +np.sqrt(u)
x = u
y = v/5.01 * np.sqrt(u)
arg = x - y**2
if arg < 0:
arg = 0
z = np.sqrt(arg)
return [x,y,z]
def lower(u, v):
# parametrize u as x and v as y
#
x = u
y = v if abs(v) < np.sqrt(u) else np.sign(v)*np.sqrt(u)
arg = x - y**2
if arg < 0:
arg = 0
z = -np.sqrt(arg)
return [x,y,z]
start_color = BLUE
end_color = YELLOW
paraboloid = Surface(
lambda u, v: axes.c2p(*upper(u, v)),
u_range=[0.01, 5],
v_range=[-5, 5],
resolution=20,
checkerboard_colors=[start_color, end_color],
fill_opacity=0.75,
stroke_color=BLUE,
stroke_width=0.5,
)
self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES)
self.add(axes)
self.add(paraboloid)
self.wait()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论