forked from zzzqzhou/Dual-Normalization
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bezier_curve.py
54 lines (43 loc) · 1.55 KB
/
bezier_curve.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import numpy as np
import random
import matplotlib.pyplot as plt
try:
from scipy.special import comb
except:
from scipy.misc import comb
def bernstein_poly(i, n, t):
"""
The Bernstein polynomial of n, i as a function of t
"""
return comb(n, i) * ( t**(n-i) ) * (1 - t)**i
def bezier_curve(points, nTimes=1000):
"""
Given a set of control points, return the
bezier curve defined by the control points.
Control points should be a list of lists, or list of tuples
such as [ [1,1],
[2,3],
[4,5], ..[Xn, Yn] ]
nTimes is the number of time steps, defaults to 1000
See http://processingjs.nihongoresources.com/bezierinfo/
"""
nPoints = len(points)
xPoints = np.array([p[0] for p in points])
yPoints = np.array([p[1] for p in points])
t = np.linspace(0.0, 1.0, nTimes)
polynomial_array = np.array([bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints)])
xvals = np.dot(xPoints, polynomial_array)
yvals = np.dot(yPoints, polynomial_array)
return xvals, yvals
def nonlinear_transformation(x, prob=0.5):
if random.random() >= prob:
return x
points = [[0, 0], [random.random(), random.random()], [random.random(), random.random()], [1, 1]]
xvals, yvals = bezier_curve(points, nTimes=100000)
if random.random() < 0.5:
# Half change to get flip
xvals = np.sort(xvals)
else:
xvals, yvals = np.sort(xvals), np.sort(yvals)
nonlinear_x = np.interp(x, xvals, yvals)
return nonlinear_x