# Quest For A Python Circle

Ok,
This thread is dedicated to creating a python script that will make a valid circle in Blender.
You should be able for pass it a radius and it will generate a bezier curve circle.
That said, here is what I know about point on a circle code: (I am learning python and don’t have the syntax, so I am posting VB for now.)

``````
for n = 0 to 360
y = sin (n) * radius
next

``````

Ok, yeah, we have point on a circle. let’s turn it into a function.

``````
for n = 0 to 360 step (360/passedPointCount)
y = sin(n) * passed Radius
tempArray (n) = trim\$(x) & "," & trim\$(y)
next
return tempArray

``````

Ok, I know that is a hack, but the intention is to have a funtion that will return an array of points when you give it a radius and point count.
So now we have an array of x,y coordinates that are points on a circle at a given radius.
Time for python now…

Here is code directly from the Blender API site.

``````
from Blender import Curve, Object, Scene
c = Curve.New() # create new curve data
cur = Scene.getCurrent() # get current scene
ob = Object.New('Curve') # make curve object

``````

This code, of course, does not work and crashes on line 1.
But the basic premise is here.

The question is, how do I link my array of coordinates into these objects?

A bezier circle can be defined by four points (knots) equally spaced around the circle. Actually you could probably do it with any number >= 2 if you were tricky. With four though you only need to create auto handles and the circle shall appear…

There is unfortunatly a bug in Blender 2.42a that prevents curve handles from being recalculated when they are made by a script. I think it is fixed in cvs though. If you want I could post some code to draw a bezier circle.

Drawing a circle with a mesh on the other hand is a much more difficult problem. With curves you should define as few control points as possible because the curve will interpolate between points - that is the point of using curves! On a mesh though you can only make straight segments, so you have to decide how many verts to put around a circle, and of course bigger circles will need more verts to stay smooth…

Yes,
I would love to see code posted, could you?

Gimme a little bit, the code I have is part of a larger script…

Okay, that was easy:

``````import Blender

from Blender import BezTriple, Curve, Mathutils, Object, Scene
c = Curve.New()             # create new  curve data
cur = Scene.getCurrent()    # get current scene
ob = Object.New('Curve')    # make curve object

center = (5,5,0)

AUTO = BezTriple.HandleTypes.AUTO
# Build four points at radius distance in the four cardnal directions

p1 = BezTriple.New(p1)
p2 = BezTriple.New(p2)
p3 = BezTriple.New(p3)
p4 = BezTriple.New(p4)

# Can't have a curve without points...
curve = c.appendNurb(p1)
curve.append(p2)
curve.append(p3)
curve.append(p4)

# Set both handles to auto for each point
for point in curve:
point.handleTypes = [AUTO, AUTO]
curve.flagU = 1 # Set curve cyclic
c.update()
ob.loc = center # Put it where it goes
Blender.Redraw()
``````

This is actually the test code I wrote while trying to figure out how to do this myself. I think I have a nice version wrapped in a function in the code I mentioned above, but I found this first
I tested it and it works under the current cvs! On 2.42a it draws a square instead of a circle though :rolleyes:

Thanks for the post,
Here is what I came up with…

``````
#Create a circular path for Blender 2.42a
import Blender
from Blender import *
import math
from math import *

c = Curve.New()
c.setPathLen(300)
c.setFlag(8)

z = 0         # 2D Drawing for now.
w = 1         #Weight is 1.
final_x = 0
final_y = 0
angleStep = 360/ passedNumberOfPoints
for ang in range(0, 359,angleStep):
if (ang ==0):
final_x = x
final_y = y
c.appendNurb([x,y,z,w])
c[0].type = 0      # Poly line
else:
c.appendPoint(0,[x,y,z,w,0])  # Can add tilt here with w.
c.appendPoint(0,[final_x,final_y,z,w,0]) # Can add tilt here.
c.update()
scn = Scene.GetCurrent()     # New Curve and add to Scene.
ob = Object.New('Curve')
ob.setName ("PolyBezier")