TypeError: LinearGradient.__new__() 需要精确的4个参数(只提供了2个)

huangapple go评论66阅读模式
英文:

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) 要绘制的函数需要返回三个值即xy和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)

TypeError: LinearGradient.__new__() 需要精确的4个参数(只提供了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()

TypeError: LinearGradient.__new__() 需要精确的4个参数(只提供了2个)

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()

TypeError: LinearGradient.__new__() 需要精确的4个参数(只提供了2个)

huangapple
  • 本文由 发表于 2023年6月13日 05:59:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460579.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定