As part of a homework assignment, Im trying to create bezier curves (with 4 points) with a maximum finite curvature of K_x. Curvature is calculated with a defined formula k = |y''|/(1+y'^2)^1.5
FOr a set of 4 points where p0=(0,0) and p3=(0.3,0) and p1,p2 are the degree of freedom.
What I tried is to take the space of the square between [(0,0), (0,0.15), (0.3,0.15), (0,-0.15)] and scan it such that for every point p1 I pick (which because of symmetry I choose it only to be in the top right quarter) I scan all possible p2 and for each option I check whether the curve meets the condition of the curvature and if so I save the points that meet the condition.
import numpy as npimport scipy as scfrom matplotlib import pyplot as pltdef bezzier_curve(p0, p1, p2, p3, t): b0 = b_in_calc(3, 0, t) * np.transpose(p0) b1 = b_in_calc(3, 1, t) * np.transpose(p1) b2 = b_in_calc(3, 2, t) * np.transpose(p2) b3 = b_in_calc(3, 3, t) * np.transpose(p3) b = b0 + b1 + b2 + b3 return bdef b_in_calc(n, i, t): b = sc.special.binom(n, i) t1 = np.power(1-t, n-i) t2 = np.power(t, i) return b*t1*t2def numerical_deriv(y, x): # finding numerical derivative of the finction dx = np.gradient(x) dy = np.gradient(y) d = dy/dx return dk_max_allowed = 5d = 0.3p0 = np.zeros([1, 2])p3 = np.array([[0.3, 0]])p1 = np.zeros([1, 2])p2 = np.zeros([1, 2])t = np.linspace(0, 1, 10000)P1_space = np.linspace(0, d/2, num=40)P2_xspace = np.linspace(0, d, endpoint=False, num=40)P2_yspace = np.linspace(-d/2, d/2, 40)output_name = 'desired_coordinates_K_max_5.txt'condition = 0 # if we started writing P1 or notcondition1 = 0 # if we already wrote at least 1 P2 pointwith open(output_name, 'w',encoding='utf-8') as f: for i in range(1, len(P1_space)): p1[0, 0] = P1_space[i] for j in range(1, len(P1_space)): p1[0, 1] = P1_space[j] for n in range(1, len(P2_xspace)): p2[0,0] = P2_xspace[n] for m in range(len(P2_yspace)): p2[0,1] = P2_yspace[m] # create bezier curve bezz = bezzier_curve(p0, p1, p2, p3, t) x_vec = bezz[0, :] y_vec = bezz[1, :] #fig=plt.figure(1,figsize=(6,6)) #ax=plt.subplot(111); #plt.plot(x_vec, y_vec) # interpolate points to spread them x_interp = np.linspace(0, d, len(t), endpoint=True) y_interp = np.interp(x_interp, x_vec, y_vec) # derive and find curvature vector and max k y_deriv = numerical_deriv(y_interp, x_interp) y_deriv2 = numerical_deriv(y_deriv, x_interp) k_vec = y_deriv2/(1 + y_deriv**2)**1.5 k_max = np.amax(k_vec) # check if meets condition, if so write it to .txt file if k_max <= k_max_allowed: if condition == 0: f.write('P1:'+ str(P1_space[int(i)]) +','+ str(P1_space[int(j)]) +'\n') condition = 1 if condition1 ==0: f.write('P2:') condition1 = 1 f.write(str(P2_xspace[n]) +','+ str(P2_yspace[m]) +'|') condition = 0 condition1 = 0 f.write('\n')f.close()plt.text(5,5 , 'Complete', fontsize = 22)plt.xlim(0, 15)plt.ylim(0, 10)plt.show()My problem is when I read the file and try a quite a few points, I see that some of the points give curves with higher curvature then K_max I desired. I'd appreciate an advice on what conditions/constrains to add in order to fix this. maybe I should limit the space from which I can pick p2?
I would appreciate an answer with the numerical derivative because as I interpret the results I also use numerical derivative
I want to be able to make sure that the maximal curvature is less then K_max. I use a numerical derivation but the result didn't change when I did analytical derivation for the curve