Source code for Curves_Functions

# -*- coding: utf-8 -*-
"""
Created on Wed Jan 24 15:49:14 2024

@author: marti
"""


import numpy as np 
import matplotlib.pyplot as plt
from scipy.integrate import quad
import scipy.integrate as integrate
from scipy.optimize import fsolve
from scipy.special import fresnel
plt.rcParams.update({"font.size":22})


[docs] class Curves: def __init__(self, Span_X, Span_Y, Length): self.Span_X = Span_X self.Span_Y = Span_Y self.Length = Length self.t = np.arange(0, 1, 1/self.Length) self.x_Points = [] self.y_Points = []
[docs] def Bezier_Curve(self): """ The Cubic Bezier Polynoms are taken from Wikipedia! Returns ------- curve : 2 dimentional np array curve[:,0] - X Param of the Bezier Curve curve[:,1] - Y Param of the Bezier Curve """ for i in range(len(self.t)): self.x_Points.append(float((1-self.t[i])**3*0 + 3*(1-self.t[i])**2*self.t[i]*self.Span_X/2 + 3*(1-self.t[i])*self.t[i]**2*self.Span_X/2 + self.t[i]**3*self.Span_X)) self.y_Points.append(float(((1-self.t[i]**3)*0 + 3*(1-self.t[i])**2*self.t[i]*0 + 3*(1-self.t[i])*self.t[i]**2*self.Span_Y + self.t[i]**3*self.Span_Y))) x_Points = np.array(self.x_Points,dtype=float) y_Points = np.array(self.y_Points,dtype=float) curve = np.vstack((x_Points, y_Points)).T return curve
[docs] def Cosinus_Curve(self): ''' The cosinus function is SpanY*(cos((pi/(2*SpanX))*t)^2) ---->> t in the range of 0 to SpanY Returns ------- curve : 2 dimentional np array curve[:,0] - X Param of the Bezier Curve curve[:,1] - Y Param of the Bezier Curve ''' P = self.Span_Y L = self.Span_X stepSize = L/len(self.t) t = np.arange(0,L, stepSize) Func = P*(np.cos((np.pi/(2*L))*t)**2) curve = np.vstack((t, Func[::-1])).T return curve
[docs] def Euler_Curve(self): """ Returns a smooth, continuous-curvature Euler S-bend from (0, 0) to (Span_X, Span_Y) using Fresnel integrals and linear curvature. """ Span_X = self.Span_X Span_Y = self.Span_Y num_pts = self.Length # Arc length parameter # s = np.arange(-1, 1, 2/num_pts) s = np.linspace(-1, 1, num_pts) # Fresnel integrals (Euler spiral) S, C = fresnel(s) # Normalize to range [-1, 1] C = C - C[0] S = S - S[0] C = C / (C[-1] - C[0]) S = S / (S[-1] - S[0]) # Euler spiral from -90° to +90° → makes an S-bend x = S * Span_X y = C * Span_Y curve = np.vstack((x, y)).T return curve
# obj = Curves(50,20,100) # curve = obj.Bezier_Curve() # curve2 = obj.Cosinus_Curve() # plt.figure() # plt.plot(curve[:,0], curve[:,1], label = "Bezier") # plt.plot(curve2[:,0], curve2[:,1], label = "Cosinus") # plt.xlabel("L/ $\mu m$") # plt.ylabel("P/ $\mu m$") # plt.legend(loc = "best") # plt.grid() # plt.show() # import matplotlib.pyplot as plt # def euler_method(func, y0, t0, tn, h): # """ # Approximate the solution of the ODE using Euler's method. # Parameters: # func: The differential equation function, f(t, y). # y0: Initial value of the dependent variable. # t0: Initial value of the independent variable. # tn: Final value of the independent variable. # h: Step size. # Returns: # Two lists containing the values of t and y at each step. # """ # t_values = [t0] # y_values = [y0] # while t_values[-1] < tn: # t = t_values[-1] # y = y_values[-1] # y_next = y + h * func(t, y) # t_values.append(t + h) # y_values.append(y_next) # return t_values, y_values # # Example: Solve the ODE dy/dt = -2 * y with y(0) = 1 # def differential_equation(t, y): # return -2 * y # t0, tn = 0, 4 # y0 = 20 # h = 0.1 # t_values, y_values = euler_method(differential_equation, y0, t0, tn, h) # # Plot the solution # plt.plot(t_values, y_values, label='Euler Method') # plt.title("Euler's Method for dy/dt = -2y") # plt.xlabel('t') # plt.ylabel('y(t)') # plt.legend() # plt.show() # import scipy.integrate as integrate # from scipy.optimize import fsolve # R_eff = 6 # effective radius of the bend # A = 1.3 # clothoid parameter # L_max = 0 # starting point of L_max # precision = 0.05 # increasement of L_max at each iteration # tolerance = 0.01 # difference tolerance of the derivatives # # determine L_max # while True: # L_max = L_max + precision # update L_max # Ls = np.linspace(0, L_max, 50) # L at (x1,y1) # x1 = np.zeros(len(Ls)) # x coordinate of the clothoid curve # y1 = np.zeros(len(Ls)) # y coordinate of the clothoid curve # # compute x1 and y1 using the above integral equations # for i, L in enumerate(Ls): # y1[i], err = integrate.quad(lambda theta: A * np.sin(theta**2 / 2), 0, L / A) # x1[i], err = integrate.quad(lambda theta: A * np.cos(theta**2 / 2), 0, L / A) # # compute the derivative at L_max # k = -(x1[-1] - x1[-2]) / (y1[-1] - y1[-2]) # xp = x1[-1] # yp = y1[-1] # # check if the derivative is continuous at L_max # R = np.sqrt( # ((R_eff + k * xp - yp) / (k + 1) - xp) ** 2 # + (-(R_eff + k * xp - yp) / (k + 1) + R_eff - yp) ** 2 # ) # if np.abs(R - A**2 / L_max) < tolerance: # break # # after L_max is determined, R_min is also determined # R_min = A**2 / L_max # # getting the coordinates of the second clothoid curve by mirroring the first curve with respect to y=-x+R_eff # x3 = np.flipud(R_eff - y1) # y3 = np.flipud(R_eff - x1) # # solve for the parameters of the circular curve # def circle(var): # a = var[0] # b = var[1] # Func = np.empty((2)) # Func[0] = (xp - a) ** 2 + (yp - b) ** 2 - R_min**2 # Func[1] = (R_eff - yp - a) ** 2 + (R_eff - xp - b) ** 2 - R_min**2 # return Func # a, b = fsolve(circle, (0, R_eff)) # # calculate the coordinates of the circular curve # x2 = np.linspace(xp + 0.01, R_eff - yp - 0.01, 50) # y2 = -np.sqrt(R_min**2 - (x2 - a) ** 2) + b # # obtain the coordinates of the whole Euler bend by concatenating three pieces together # x_euler = np.concatenate((x1, x2, x3)) # y_euler = np.concatenate((y1, y2, y3)) # # the conventional circular bend is simply given by a circle # x_circle = np.linspace(0, R_eff, 100) # y_circle = -np.sqrt(R_eff**2 - (x_circle) ** 2) + R_eff # # plotting the shapes of the Euler bend and the circular bend # plt.plot(x_euler, y_euler, label="Euler bend") # plt.plot(x_circle, y_circle, "--", label="Circular bend") # plt.axis("equal") # plt.ylim(-1, R_eff + 1) # plt.legend() # plt.show()