Thursday, June 5, 2014

16. Bezier curves

Bezier curves are a vertex canvas instruction. A Bezier curve is weighted by some control points, that we include within the instruction.




For the case of 4 control points, P1, P2, P3, and P4, we will see how the weights work. The Bezier curve will be dependent on a parameter t, which goes from 0 to 1. At a t of 0, P1 weight is 1, that is the curve is at that point.




As t increases to 0.33, P1 weight decreases and P2 increases to a maximum value. The Bezier curve at that point will be a linear combination of all 4-points, however P2 dominates.




At t = 0.67, P1 weight is almost zero, P2 has decreased and P3 is at a maximum. The linear combination of the weights will get the Bezier curve at that t. However, it should be close to P3.




Finally, at t = 1, the Bezier curve has only weight due to P4, thus it coincides with that point.




This article discusses the Bezier curve. The equation for the curve is labeled B here, and it is a function of t. It is a linear combination of weights for the different points.




A Python program to solve and plot the Bezier curve is shown. It uses two libraries, matplotlib and scipy. P is a tuple, of the x,y coordinates, which will form, the set of the control points.




px and py are lists holding the Bezier curve at different t points. The lists are of length 51, as they vary t from 0, .02, .04 , etc, all the way to 1.




Next, the control point tuple P is unpacked to give individual x and y coordinates in xp and yp.




These are the graphing equations for the matplotlib library. The most important equation is the plot. First the control points are drawn as diamond markers and as line segments. Then the Bezier curve is plotted with the dot marker.


# bezier.py

import matplotlib.pyplot as plt
from scipy.special import binom

P=(0,300),(0,600),(400,600),(800,300),(0,0),(0,300)

n = len(P)-1
Num_t=50
px, py = [None]*(Num_t+1),[None]*(Num_t+1)

for j in range(Num_t+1):
    t = j / float(Num_t)
    px[j],py[j]=0.0,0.0
    for i in range(len(P)):
        px[j] += binom(n,i)*t**i*(1-t)**(n-i)*P[i][0]
        py[j] += binom(n,i)*t**i*(1-t)**(n-i)*P[i][1]

xp=[None]*len(P)
yp=[None]*len(P)
for i in range(len(P)): xp[i],yp[i]=P[i]

plt.title('bezier curve')
plt.xlim([min(xp)-10,max(xp)+10])
plt.ylim([min(yp)-10,max(yp)+10])
plt.xlabel('x')
plt.ylabel('y')
plt.text(25,300,'P1,P6')
plt.text(15,575,'P2')
plt.text(375,575,'P3')
plt.text(750,300,'P4')
plt.text(15,25,'P5')
plt.plot(xp,yp,'-d',px,py,'.')
plt.grid()
plt.show()




This is shown here. There are 6 control points, however P1 and P6 are the same. This shows that with a few points, we can get a complicated curve. Note that the width of this Bezier curve is a little less than 400. Thus, if control points are given, such that all x-components have increased by 400, we could get 2 such curves if our window-width is 800. Since the first and last control points are the same value, the Bezier curve is closed.




This Python program will start the Kivy program to draw the Bezier curves. It is based on BoxLayout.


# ex16.py

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App

class Ex16(BoxLayout):
    pass
   
class Ex16App(App):
    def build(self):
        return Ex16()

if __name__=='__main__':
    Ex16App().run()



In the kv file, first the window color is set.




Next we have 3 Bezier curves. Each has a different color. The first corresponds to the six points we have seen. The other 2 are x-displaced by 200 pixels or 400 pixels. For the one displaced by 200 pixels, it should begin halfway, and the one displayed by 400 pixels, and colored purple, it should begin after the first one finishes.


# ex16.kv

<Ex16>:
    canvas:
        Color:
            rgb: .9,.95,1
        Rectangle:
            pos: self.pos
            size: self.size
        Color:
            rgb: 1,0,0
        Bezier:
            points: 0,300, 0,600, 400,600, 800,300, 0,0, 0,300
            segments: 100
        Color:
            rgb: 0,.5,.5
        Bezier:
            points: 200,300, 200,600, 600,600, 1000,300, 200,0, 200,300
            segments: 100
        Color:
            rgb: .5,0,.5
        Bezier:
            points: 400,300, 400,600, 800,600, 1200,300, 400,0, 400,300
            segments: 100     



This shows the result. Here are three Bezier curves, which are closed because the starting and ending points are the same. The only difference between the curves is that the control points were x-displaced by either 200 pixels or 400 pixels.




1 comment:

  1. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.

    Python Training in electronic city

    ReplyDelete