def generate_rotation_surface(spl, num_samples): ss = spline_surface(3) # Jeder Kontrollpunkt des Eingabesplines müssen um die z-Achse rotiert werden d = spl.control_points c = [[vec3(0, 0, 0)] * num_samples for i in range(len(d))] for i in range(len(d)): for j in range(num_samples): k_x = d[i].x * math.cos(2 * math.pi * j / num_samples) k_y = d[i].x * math.sin(2 * math.pi * j / num_samples) k_z = d[i].y c[i][j] = vec3(k_x, k_y, k_z) #Für jedes feste i interpolieren wir die Punkte ci0, . . . , ci,R−1 wie in Versuch 2 b = [[vec3(0, 0, 0)] * (num_samples + 3) for i in range(len(d))] for i in range(len(d)): pts = [vec2(0, 0)] * num_samples for j in range(num_samples): pts[j] = vec2(c[i][j].x, c[i][j].y) s = spline.interpolate_cubic_periodic(pts) #Kontrollpunkte bij ∈ R3. (Für festes i liegen die bij in der Ebene z = zi.) for k in range(num_samples + 3): l_x = s.control_points[k].x l_y = s.control_points[k].y l_z = d[i].y b[i][k] = vec3(l_x, l_y, l_z) u = spl.knots v = s.knots ss.knots = (u, v) ss.control_points = b return ss
def solve_almost_tridiagonal_equation(diag1, diag2, diag3, res): assert (len(diag1) == len(diag2) == len(diag3) == len(res)) res_x = [el.x for el in res] res_y = [el.y for el in res] sol_x = solve_almost_tridiagonal_equation_one_coordinate( diag1, diag2, diag3, res_x) sol_y = solve_almost_tridiagonal_equation_one_coordinate( diag1, diag2, diag3, res_y) return [vec2(sol_x[i], sol_y[i]) for i in range(len(res))]
def write_image(self): if self.elements == []: print("empty scene") return resolution = self.resolution margin = self.margin bb_bl, bb_tr = self.bounding_box scene_width = (bb_tr - bb_bl).x scene_height = (bb_tr - bb_bl).y aspect_ratio = scene_width / scene_height #determine which side's length is set to self.resolution pixels if aspect_ratio > 1: image_width = resolution image_height = int( (resolution - 2 * margin) / aspect_ratio) + 2 * margin elif aspect_ratio < 1: image_width = int( (resolution - 2 * margin) * aspect_ratio) + 2 * margin image_height = resolution else: image_width = resolution image_height = resolution #calculate a transformation from object space to image space. #in image space, the y coordinate points downwards #print("calculationg transform") #print("scene w,h,w/h", scene_width, scene_height, aspect_ratio) #print("image w,h", image_width, image_height) scale = (image_width - 2 * margin) / scene_width offset = -vec2(scale * bb_bl.x, -scale * bb_bl.y) + vec2( margin, image_height - margin) #print("scale, offset", scale, offset) transform = lambda v: vec2(scale * v.x, -scale * v.y) + offset self.transform = transform #generate the image self.image = Image.new("RGB", (image_width, image_height), self.background) for elem in self.elements: elem.draw(self, self.num_samples)
def construct_parallel(self, dist): pts = [] knotss = [self(t) for t in self.knots[3:-3]] for i in range(len(knotss)): tang = self.tangent(self.knots[3:-3][i]) #print("knot", self.knots[3:-3][i]) #print("tan", tang.x, tang.y, end="\n\n") x = (tang.y / sqrt(tang.x ** 2 + tang.y ** 2)) * dist y = -(tang.x / sqrt(tang.x ** 2 + tang.y ** 2)) * dist pts.append(vec2(knotss[i].x + x, knotss[i].y + y)) s = spline.interpolate_cubic(self.INTERPOLATION_CHORDAL, pts) return s
def interpolate_cubic(mode, points): s = spline(3) s.control_points = points n = len(points) # Parametrisierung t = [0.] * n if mode == 0: for i in range(n): t[i] = i elif mode == 1: for i in range(1, n): t[i] = math.sqrt((points[i] - points[i - 1]).x ** 2 + (points[i] - points[i - 1]).y ** 2) + t[i - 1] elif mode == 2: for i in range(1, n): t[i] = ((points[i] - points[i - 1]).x ** 2 + (points[i] - points[i - 1]).y ** 2) ** 0.25 + t[i - 1] elif mode == 3: d = [0.] * n # chordale for i in range(0, n - 1): d[i] = math.sqrt((points[i + 1] - points[i]).x ** 2 + (points[i + 1] - points[i]).y ** 2) alpha = [0.] * n for i in range(1, n - 1): a1 = points[i - 1].y - points[i].y b1 = points[i].x - points[i - 1].x a2 = points[i].y - points[i + 1].y b2 = points[i + 1].x - points[i].x angle = math.acos((b1 * b2 + a1 * a2) / (math.sqrt(b1 ** 2 + a1 ** 2) * math.sqrt(b2 ** 2 + a2 ** 2))) alpha[i] = min(math.pi - angle, math.pi / 2) for i in range(1, n): if i == 1: k = 0 else: k = 3 / 2 * alpha[i - 1] * d[i - 2] / (d[i - 2] + d[i - 1]) l = 3 / 2 * alpha[i] * d[i] / (d[i] + d[i - 1]) t[i] = d[i - 1] * (1 + k + l) + t[i - 1] # print(t) # Knot vector m = len(t) u = [0.] * (m + 6) # corresponds t in Assignment, 6 is adding 3 points left and 3 points right u[0], u[1], u[2] = float(t[0]), float(t[0]), float(t[0]) # t1 =t2 = t3 for i in range(m): u[i + 3] = float(t[i]) u[m + 3], u[m + 4], u[m + 5] = float(t[m - 1]), float(t[m - 1]), float(t[m - 1]) knots_t = knots(len(u)) knots_t.knots = u s.knots = knots_t # print("u = ", u) # creating of the equation Ax=p # A is tridiagonal and consists of main_diag, upper_diag and under_diag # p consists of elements of type vec2 namely points # calculating p p = [0] * (n + 2) p[0] = points[0] p[1] = vec2(0.0, 0.0) p[n + 1] = points[n - 1] p[n] = vec2(0.0, 0.0) p[2:n] = points[1:(n - 1)] # calculating A main_diag = [0.] * (n + 2) under_diag = [0.] * (n + 2) upper_diag = [0.] * (n + 2) for i in range(2, n): # print("i = ", i) ai = (u[i + 2] - u[i]) / (u[i + 3] - u[i]) bi = (u[i + 2] - u[i + 1]) / (u[i + 3] - u[i + 1]) ci = (u[i + 2] - u[i + 1]) / (u[i + 4] - u[i + 1]) # print("ai, bi, ci = ", ai, bi, ci, sep=" ", end="\n") under_diag[i] = (1 - bi) * (1 - ai) main_diag[i] = (1 - bi) * ai + bi * (1 - ci) upper_diag[i] = bi * ci main_diag[0] = 1.0 main_diag[n + 1] = 1.0 main_diag[1] = 1 + (u[4] - u[2]) / (u[5] - u[2]) main_diag[n] = - (u[n + 1] - u[n]) / (u[n + 3] - u[n]) + 2 upper_diag[n] = -1.0 upper_diag[n + 1] = .0 upper_diag[0] = .0 upper_diag[1] = - (u[4] - u[2]) / (u[5] - u[2]) under_diag[0] = .0 under_diag[1] = -1.0 under_diag[n + 1] = .0 under_diag[n] = -1.0 + (u[n + 1] - u[n]) / (u[n + 3] - u[n]) p_x = [el.x for el in p] p_y = [el.y for el in p] # print("main upper under p_x p_y:", main_diag, upper_diag, under_diag, p_x, p_y, sep="\n") # solve equation Ax = p x = utils.solve_tridiagonal_equation(under_diag, main_diag, upper_diag, p) # divion by 0!!! s.control_points = x return s
l_x = s.control_points[k].x l_y = s.control_points[k].y l_z = d[i].y b[i][k] = vec3(l_x, l_y, l_z) u = spl.knots v = s.knots ss.knots = (u, v) ss.control_points = b return ss pts = [ vec2(0.05, 6), vec2(0.2, 6), vec2(1, 5), vec2(.25, 4), vec2(1, 3.75), vec2(.55, 3.5), vec2(.5, 3.4), vec2(.5, .6), vec2(.55, .5), vec2(0.8, 0.2), vec2(.95, 0.1), vec2(1, 0) ] spl = spline.interpolate_cubic(spline.INTERPOLATION_CHORDAL, pts) #you can activate these lines to view the input spline
#!/usr/bin/python from cagd.polyline import polyline from cagd.spline import spline, knots from cagd.vec import vec2 import cagd.scene_2d as scene_2d #create an example spline to demonstrate how to create a spline #you can use this to test your implementation of the de-boor algorithm # and the knot_index function example_spline = spline(3) example_spline.control_points = [ vec2(0, 0), vec2(0, 1), vec2(1, 1), vec2(1, 0), vec2(2, 0) ] example_spline.knots = knots(9) example_spline.knots.knots = [0, 0, 0, 0, 1, 2, 2, 2, 2] p = example_spline.get_polyline_from_control_points() p.set_color("red") #interpolate six points with the four different interpolation options to # draw a small letter "e" #uncomment these lines once you implemented the spline interpolation pts = [ vec2(0, .4), vec2(.8, .8), vec2(.5, 1.2), vec2(-.03, .4), vec2(.4, 0), vec2(1, .2)
#!/usr/bin/python from cagd.polyline import polyline from cagd.spline import spline from cagd.vec import vec2 import cagd.scene_2d as scene_2d from math import sqrt pts = [ vec2(0, .4), vec2(.8, .8), vec2(.5, 1.2), vec2(-.03, .4), vec2(.4, 0), vec2(1, .2) ] s1 = spline.interpolate_cubic(spline.INTERPOLATION_CHORDAL, pts) s1.set_color("#0000ff") sc = scene_2d.scene() sc.set_resolution(900) sc.add_element(s1) for i in [-1, 1]: para = s1.generate_parallel(i * 0.025, 0.005) para.set_color("#999999") sc.add_element(para) #para = s1.generate_parallel(-1 * 0.025, 0.005) #para.set_color("#999999") #sc.add_element(para)
def unit_circle_points(num_samples): a = 2 * pi / num_samples return [vec2(cos(a * i), sin(a * i)) for i in range(num_samples)]
#the Manhattan Metrics is chosen def calculate_circle_deviation(spline): ideal_d = 1.0 center_x = 0.0 center_y = 0.0 deviation = 0.0 for p in spline.control_points: deviation += sqrt((p.x - center_x)**2 + (p.y - center_y)**2) deviation /= len(spline.control_points) deviation -= ideal_d return deviation #interpolate 6 points with a periodic spline to create the number "8" pts = [ vec2(0, 2.5), vec2(-1, 1), vec2(1, -1), vec2(0, -2.5), vec2(-1, -1), vec2(1, 1) ] s = spline.interpolate_cubic_periodic(pts) p = s.get_polyline_from_control_points() p.set_color("blue") sc = scene_2d.scene() sc.set_resolution(900) sc.add_element(s) sc.add_element(p) #generate a spline that approximates the unit circle