简体   繁体   中英

Bezier Curve using static points

So I found this code on line and it does a random Bezier Curve which uses random points. I was trying to make it non random so that it would use static points I got it to use only 4 points which was easy. I have never used PIL before in python and in fact I am slowly learning python. And I have only really done front end work (html, javascript, css, etc) and I just wanted to know if some one can help me. Here is the code I found on line:

# Random Bezier Curve using De Casteljau's algorithm
# http://en.wikipedia.org/wiki/Bezier_curve
# http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm
# FB - 201111244
import random
from PIL import Image, ImageDraw
imgx = 500
imgy = 500
image = Image.new("RGB", (imgx, imgy))
draw = ImageDraw.Draw(image)

def B(coorArr, i, j, t):
    if j == 0:
        return coorArr[i]
    return B(coorArr, i, j - 1, t) * (1 - t) + B(coorArr, i + 1, j - 1, t) * t

n = 4 # number of control points
coorArrX = []
coorArrY = []
for k in range(n):
    x = (0, imgx - 1)
    y = (0, imgy - 1)
    coorArrX.append(x)
    coorArrY.append(y)

# plot the curve
numSteps = 10000    
for k in range(numSteps):
    t = float(k) / (numSteps - 1)
    x = int(B(coorArrX, 0, n - 1, t))
    y = int(B(coorArrY, 0, n - 1, t))
    try:
        image.putpixel((x, y), (0, 255, 0))
    except:
        pass

# plot the control points
cr = 3 # circle radius
for k in range(n):
    x = coorArrX[k]
    y = coorArrY[k]
    try:
        draw.ellipse((x - cr, y - cr, x + cr, y + cr), (255, 0, 0))
    except:
        pass

# image.save("BezierCurve.png", "PNG")
image.show() I add this so I can see it right away

Any help if at all would be great.

Ok The long detailed BS that began this all is below the long line. The resulting answer is here.

Your static points are x,y coordinates with the x values and y values placed in seperate arrays (coorArrx and coorArrY respectively) make sure to never use a value = imgx or imy.

# Random Bezier Curve using De Casteljau's algorithm
# http://en.wikipedia.org/wiki/Bezier_curve
# http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm
# FB - 201111244
import random
from PIL import Image, ImageDraw
imgx = 500
imgy = 500
image = Image.new("RGB", (imgx, imgy))
draw = ImageDraw.Draw(image)

def B(coorArr, i, j, t):
    if j == 0:
        return coorArr[i]
    return B(coorArr, i, j - 1, t) * (1 - t) + B(coorArr, i + 1, j - 1, t) * t

# n = random.randint(3, 6) # number of control points
n=4
#coorArrX = []
#coorArrY = []
#for k in range(n):
#    x = random.randint(0, imgx - 1)
#    y = random.randint(0, imgy - 1)
#    coorArrX.append(x)
#    coorArrY.append(y)
coorArrX=[3,129,12,77]
coorArrY=[128,52,12,491]

# plot the curve
numSteps = 10000
for k in range(numSteps):
    t = float(k) / (numSteps - 1)
    x = int(B(coorArrX, 0, n - 1, t))
    y = int(B(coorArrY, 0, n - 1, t))
    try:
        image.putpixel((x, y), (0, 255, 0))
    except:
        pass

# plot the control points
cr = 3 # circle radius
for k in range(n):
    x = coorArrX[k]
    y = coorArrY[k]
    try:
        draw.ellipse((x - cr, y - cr, x + cr, y + cr), (255, 0, 0))
    except:
        pass
image.show()

=.........................................................................................= I am also something of a newcommer to all of this, and I REFUSE to look this up as I see it like you do...a learning experiencee.

But as I look at this code I see something strange

for k in range(n):
    x = (0, imgx - 1)
    y = (0, imgy - 1)
    coorArrX.append(x)
    coorArrY.append(y)

Are you sure this part is correct? imgx is defined as 500 elsewhere, and n is 4. so this could read as

for k in range(4):
    x = (0, 500 - 1)
    y = (0, 500 - 1)

which (since these values never change at all in this code) means:

x = (0, 499)
y = (0, 499)

on every pass. So each time they get to :

coorArrX.append(x)
coorArrY.append(y)

They simply keep adding new copies of the same data to the array, so when it is done the array looks like this (internally)

[(0, 499), (0, 499), (0, 499), (0,499)]

What makes this more confusing, is that coorArrX and coorArrY are A) Identical, and B) identical in their basic parts(that is each element is identical). Therefore, when you get to this part of the code:

# plot the control points
cr = 3 # circle radius
for k in range(n):
    x = coorArrX[k]
    y = coorArrY[k]
    try:
        draw.ellipse((x - cr, y - cr, x + cr, y + cr), (255, 0, 0))
    except:
        pass

and you substitute in the values in the arrays, you get:

# plot the control points
cr = 3 # circle radius
for k in range(n):
    x = coorArrX[k]
    y = coorArrY[k]
    try:
        draw.ellipse(((0, 499) - 3, (0, 499) - 3, (0, 499) + 3, (0, 499) + 3), (255, 0, 0))
    except:
        pass

Now this is the part that controls the drawing of the curved segments for the plot, but I do not see how centering an elispe on those impossible coordinate sets can draw anything?!

Broke down and did a copy paste test run. This code is purely bogus, either placed to dupe people into wasting time, or placed where OP found it for same reason.

But it was fun trying!!

From your description, the only problem seems to be about Python basics. I have rearranged the code as follows, so the only things that need to be touched are at bottom. Now, if you want to manually specify 4 control points, go ahead and do it (in the following code I have specified 4 of them myself as an example). You need to understand that, in the original code, coorArrX and coorArrY are just lists, which will hold 4 points each (x and y coordinates, respectively). If you are manually specifying them, there is no point in using a loop to write them. I hope this code is clear enough:

# Random Bezier Curve using De Casteljau's algorithm
# http://en.wikipedia.org/wiki/Bezier_curve
# http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm
# FB - 201111244
from PIL import Image, ImageDraw

def plot_curve(image, px, py, steps=1000, color=(0, 255, 0)):
    def B(coord, i, j, t):
        if j == 0:
            return coord[i]
        return (B(coord, i, j - 1, t) * (1 - t) +
                B(coord, i + 1, j - 1, t) * t)

    img = image.load()
    for k in range(steps):
        t = float(k) / (steps - 1)
        x = int(B(px, 0, n - 1, t))
        y = int(B(py, 0, n - 1, t))
        try:
            img[x, y] = color
        except IndexError:
            pass

def plot_control_points(image, px, py, radi=3, color=(255, 0, 0)):
    draw = ImageDraw.Draw(image)
    for x, y in zip(px, py):
        draw.ellipse((x - radi, y - radi, x + radi, y + radi), color)


# Your fixed, manually specified, points.
n = 4
coord_x = [25, 220, 430, 410]
coord_y = [250, 10, 450, 40]

image = Image.new("RGB", (500, 500))

plot_curve(image, coord_x, coord_y)
plot_control_points(image, coord_x, coord_y)

image.save("BezierCurve.png")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM