# Create a simple Circle Arc Line Bezier (working code 1.10)

I figured out how to draw a simple bezier curve!

I don’t know why the ’ CubicCurveseg’ class doesn’t seem to work:
CubicCurveseg class for Bezier curves

I still got Bezier to display on screen using ‘LineSegs’

``````#!/usr/bin/env python3

from direct.showbase.ShowBase import ShowBase
from panda3d.core import LineSegs
from math import comb

class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)

# Set up the camera
self.setup_camera()

# Create a LineSegs object
lines = LineSegs()

# Set the color of the curve (red)
lines.set_color(1, 0, 0, 1)

# Define the control points of the cubic Bezier curve
control_points = [
(0, 0, 0),   # Start point
(1, 0, 0),   # First control point
(0, 1, 0),   # Second control point
(1, 1, 0)    # End point
]

# Set the number of subdivisions for the curve
num_subdivisions = 100

# Draw the curve
for i in range(num_subdivisions + 1):
t = i / num_subdivisions
point = self.evaluate_cubic_bezier(control_points, t)
lines.draw_to(point)

# Create a NodePath to attach the curve geometry
curve_np = self.render.attachNewNode(lines.create())

# Set the line thickness
curve_np.setRenderModeThickness(3)

def evaluate_cubic_bezier(self, control_points, t):
n = len(control_points) - 1
result = [0, 0, 0]
for i, point in enumerate(control_points):
coeff = comb(n, i) * (1 - t)**(n - i) * t**i
for j in range(3):
result[j] += coeff * point[j]
return tuple(result)

def setup_camera(self):
self.disableMouse()
camera.setPos(0, 0, 10)
camera.lookAt(0, 0, 0)

app = MyApp()
app.run()

``````

This is how I drew a ‘ARC’

``````#!/usr/bin/env python3

from panda3d.core import LineSegs, Point3
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)

# Set up the camera
self.setup_camera()

# Create a LineSegs object
lines = LineSegs()

# Set the color of the arc (red)
lines.set_color(1, 0, 0, 1)

# Define the three points of the arc
point1 = Point3(-1, 0, 0)
point2 = Point3(0, 0, 1)
point3 = Point3(1, 0, 0)

# Calculate the arc points
arc_points = self.calculate_arc_points(point1, point2, point3)

# Draw the arc
for point in arc_points:
lines.draw_to(point)

# Create a NodePath to attach the arc geometry
arc_np = self.render.attachNewNode(lines.create())

# Set the line thickness
arc_np.setRenderModeThickness(3)

def setup_camera(self):
self.disableMouse()
self.camera.setPos(0, -10, 0)
self.camera.lookAt((0, 0, 0))

def calculate_arc_points(self, point1, point2, point3):
# Calculate the arc points using quadratic Bézier curve algorithm
num_subdivisions = 50
arc_points = []
for i in range(num_subdivisions + 1):
t = i / num_subdivisions
p0 = point1 + (point2 - point1) * t
p1 = point2 + (point3 - point2) * t
p = p0 + (p1 - p0) * t
arc_points.append(p)
return arc_points

app = MyApp()
app.run()

``````

Here is a circle

``````#!/usr/bin/env python3

from direct.showbase.ShowBase import ShowBase
from panda3d.core import LineSegs
from math import cos, sin, pi

class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)

# Set up the camera
self.setup_camera()

# Create a LineSegs object
lines = LineSegs()

# Set the color of the circle (red)
lines.set_color(1, 0, 0, 1)

# Define the center and radius of the circle
center = (0, 0, 0)

# Set the number of segments for the circle
num_segments = 50

# Draw the circle
for i in range(num_segments+1):
angle = 2.0 * pi * i / num_segments
lines.draw_to(center[0] + x, center[1] + y, center[2])

# Create a NodePath to attach the circle geometry
circle_np = self.render.attachNewNode(lines.create())

# Set the line thickness
circle_np.setRenderModeThickness(3)

def setup_camera(self):
self.disableMouse()
camera.setPos(0, 0, 10)
camera.lookAt(0, 0, 0)

app = MyApp()
app.run()

``````

Here is a simple line

``````#!/usr/bin/env python3

from direct.showbase.ShowBase import ShowBase
from panda3d.core import LineSegs

class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)

# Set up the camera
self.setup_camera()

# Create a LineSegs object
lines = LineSegs()

# Set the color of the line (red)
lines.set_color(1, 0, 0, 1)

# Define the starting and ending points of the line
start_point = (0, 0, 0)
end_point = (1, 0, 0)

# Draw the line
lines.move_to(start_point)
lines.draw_to(end_point)

# Create a NodePath to attach the line geometry
line_np = self.render.attachNewNode(lines.create())

# Set the line thickness
line_np.setRenderModeThickness(3)

def setup_camera(self):
self.disableMouse()
camera.setPos(0, -10, 0)
camera.lookAt(0, 0, 0)

app = MyApp()
app.run()

``````

Come visit my project
www.shenko.org

I don’t think that’s exactly what this post is about. At first I thought it was a joke. However, I realized that you are mistaken, since this curve is useless, it cannot be used as a path, for example, and so on.

``````from direct.showbase.ShowBase import ShowBase
from direct.showutil.Rope import Rope

class TestCurve(ShowBase):
def __init__(self):
ShowBase.__init__(self)

curve = Rope()
curve.ropeNode.set_num_subdiv(50)
curve.setup(4, [(None, (-12, 0, 0)),
(None, (0, 0, 9)),
(None, (3, 0, -8)),
(None, (12, 0, 0))])
curve.set_pos(0, 30, 0)
curve.reparent_to(render)

test_curve = TestCurve()
test_curve.run()
``````

That’s exactly the curve.

Example using weights.

``````from direct.showbase.ShowBase import ShowBase
from direct.showutil.Rope import Rope

class TestCurve(ShowBase):
def __init__(self):
ShowBase.__init__(self)

curve = Rope()
curve.ropeNode.set_num_subdiv(50)
curve.setup(4, [(None, (-12,  0,  0,  0.5)),
(None, (  0,  0,  9,  0.2)),
(None, (  3,  0, -8,  0.8)),
(None, ( 12,  0,  0,  0.1))])
curve.set_pos(0, 30, 0)
curve.reparent_to(render)

test_curve = TestCurve()
test_curve.run()``````

These were all simple few lines of code to do one simple task in case it helps anyone.

for example, when I go onto the panda3d documentation and type in ‘bezier’ (since its used often) it points me to:

# CubicCurveseg

from panda3d.core import CubicCurveseg
“”"

I have struggled for a long time to decipher the documentation, I was just trying to help if someone searched ‘Bezier’ here my hope was they find working scripts.

I plan to eventually propose / push changes to the repo to update panda3d docs, I just haven’t gotten around to it yet

Your scripts work amazing thanxs, saved it to my library spasiba

In fact, the topic of curves in panda is very confusing, looking at the implementation of `Rope` you can understand that it is implemented through `NurbsCurveEvaluator`

https://docs.panda3d.org/1.10/python/reference/panda3d.core.NurbsCurveEvaluator#nurbscurveevaluator

The problem is that it can’t be used as a path for an object, maybe I don’t have enough experience in this…

1 Like

That was on my todo list, figure out how to follow a path if I want to make a simple train.

as part of my project I was going to make a complete script for each item in documentation, a complete working script, just got delayed. Everything in documentation feels like a puzzle.

Earlier, in connection with this post, I created a low-level example, but for some reason did not publish it.

``````from direct.showbase.ShowBase import ShowBase
from panda3d.core import RopeNode, NurbsCurveEvaluator, RopeNode, Vec4, NodePath

class TestCurve(ShowBase):
def __init__(self):
ShowBase.__init__(self)

curve = NurbsCurveEvaluator()
curve.reset(4)

curve.set_vertex(0, Vec4(-12,  0,  0,  1))
curve.set_vertex(1, Vec4(  0,  0,  9,  1))
curve.set_vertex(2, Vec4(  3,  0, -8,  1))
curve.set_vertex(3, Vec4( 12,  0,  0,  1))

rope_node = RopeNode("rope")
rope_node.set_curve(curve)
rope_node.set_num_subdiv(50)
rope_node.set_thickness(2)

rope_path = NodePath(rope_node)
rope_path.set_color(Vec4(0, 1, 0, 1))
rope_path.reparent_to(render)

test_curve = TestCurve()
test_curve.run()
``````

The bad news is that this cannot be used with the `Mopath` class. But maybe I’m missing something, or this implementation is not designed for that.

1 Like

If I’m not much mistaken, one can evaluate the curve to get a NurbsCurveResult object, then evaluate that at successive points in time to get positions at which to place an object.

Something like this:

``````# In initialisation:
self.curveResult = myNurbsCurveEvaluator.evaluate(render)
self.timer = 0

self.myObject.reparentTo(render)

# Elsewhere...
dt = self.clock.getDt()

self.timer += dt

point = Vec3(0, 0, 0)
self.curveResult.evalPoint(self.timer, point)

self.myObject.setPos(point)