Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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))]
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
            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
Ejemplo n.º 7
0
#!/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)
Ejemplo n.º 8
0
#!/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)
Ejemplo n.º 9
0
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)]
Ejemplo n.º 10
0
#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