Пример #1
0
def antiprism_model(pgon, arg_type):
    """Construct antiprism model with golden trapziums"""
    N = pgon.N
    ang = pgon.angle() / 2
    P = tri_antiprism_pt(pgon, gold_trap_diag, 1, phi)
    Q = Vec(P[0], -P[1], -P[2])
    points = []
    for i in range(N):
        points.append(P.rot_z(2 * i * ang))
    for i in range(N):
        points.append(Q.rot_z(2 * i * ang))
    R = points[N - 1] + (P - Q) * phi
    for i in range(N):
        points.append(R.rot_z(2 * i * ang))
    S = Vec(R[0], -R[1], -R[2])
    for i in range(N):
        points.append(S.rot_z(2 * i * ang))

    faces = []
    faces.append([2 * N + i for i in range(N)])
    faces.append([3 * N + i for i in range(N)])
    for i in range(N):
        faces.append([i, 2 * N + i, 2 * N + ((i + 1) % N)])
        faces.append([N + i, 3 * N + i, 3 * N + ((i - 1) % N)])
        faces.append(
            [i, 2 * N + ((i + 1) % N), ((i + 1) % N), N + ((i + 1) % N)])
        faces.append([i, N + ((i + 1) % N), 3 * N + i, N + i])
    return points, faces
Пример #2
0
def get_base_points(pgon, centres=0, twist=False):
    N = pgon.N
    D = pgon.D
    a = pgon.angle()/2
    points = [Vec(0, 0, 1), Vec(0, 0, -1)]  # poles
    A = a
    B = math.pi/2 * (1 - D/N)
    cos_lat = 1/(math.tan(A) * math.tan(B))
    sin_lat = math.sqrt(1 - cos_lat**2)
    p_north = Vec(sin_lat, 0, cos_lat)
    p_south = Vec(sin_lat, 0, -cos_lat)
    for i in range(N):
        points.append(p_north.rot_z(i*2*a))
    for i in range(N):
        points.append(p_south.rot_z(i*2*a+a))
    if centres:
        cos_cent_lat = math.cos(B)/math.sin(A)
        sin_cent_lat = math.sqrt(1 - cos_cent_lat**2)
        cent_north = Vec(sin_cent_lat, 0, cos_cent_lat)
        cent_south = Vec(sin_cent_lat, 0, -cos_cent_lat)
        for i in range(N):
            points.append(cent_north.rot_z(i*2*a+a) * centres)
        for i in range(N):
            points.append(cent_south.rot_z(i*2*a) * centres)

    rhombi = []
    for i in range(N):
        rhombi.append([2 + i, 0, 2 + ((i+1) % N), 2 + N + i])
    for i in range(N):
        rhombi.append([2 + N + i, 1, 2 + N + ((i-1) % N), 2 + i])

    if twist:
        hx = [0, 2, 2 + N, 1, 2 + N+N//2, 2 + N-N//2]
        axis = points[hx[0]] + points[hx[2]] + points[hx[4]]
        rot = Mat.rot_axis_ang(axis.unit(), 2*math.pi/3)
        for i in list(range(hx[5]+1, 2 + N)) + list(range(hx[4]+1, 2 + 2*N)):
            points[i] = rot * points[i]
        if centres:
            for r in list(range(N-N//2, N+1)) + list(range(2*N-N//2, 2*N)):
                points[2 + 2*N + r] = rot * points[2 + 2*N + r]
        for r in list(range(N-N//2, N+1)) + list(range(2*N-N//2, 2*N)):
            for i in range(4):
                for idx, p_idx in enumerate(hx):
                    if p_idx == rhombi[r][i]:
                        rhombi[r][i] = hx[(idx+2) % 6]
                        break

    return points, rhombi
Пример #3
0
def j89_get_principal_verts(pgon, ang, flags):
    bad = flags.strip('ABC')
    if bad:
        raise ValueError('Unrecognised form flag(s) \''+bad+'\'')
    ridge_down = 'A' in flags
    ridge2_down = 'B' in flags
    belt_back = 'C' in flags
    pgon.N *= 2
    # p_ang2 = pgon2.angle()
    A, B, B2, C = get_pstt_cap_verts(pgon, ang, ridge_down)
    pgon.N //= 2

    p_ang = pgon.angle()/2
    A2_rad = pgon.circumradius(edge)  # circumradius of top polygon
    sq_mid = (B + B2) / 2
    sq_mid_rad = Vec(sq_mid[0], sq_mid[1], 0).mag()
    tri_ht2 = 3/4 - (A2_rad - sq_mid_rad)**2
    if tri_ht2 < -epsilon:
        raise ValueError(
            'Not possible to calculate upper equilateral triangle')

    A2_ht = (1 - 2*belt_back)*sqrt(tri_ht2) + B[2]
    A2 = Vec(A2_rad, 0, A2_ht).rot_z(p_ang/2)

    A2_minus1 = A2.rot_z(-2*p_ang)
    B2_minus1 = B2.rot_z(-2*p_ang)
    C2 = get_three_line_vert(A2_minus1, A2, B2_minus1, B, ridge2_down)
    return [pt.rot_z(p_ang/2) for pt in [A, B, B2, C, A2, C2]]
Пример #4
0
def make_frame(frame_elems, pgon, axis_angle, num_segs):
    points = []
    faces = []
    if frame_elems:
        v0 = Vec(0, 0, 1)
        v1 = Vec(-math.sin(axis_angle), 0, math.cos(axis_angle))
        v2 = v1.rot_z(pgon.angle() / 2)
        v2[2] *= -1
        if 'r' in frame_elems:
            ps, fs = make_arc(v0, v1, num_segs, 0)
            points += ps
            faces += fs
            ps, fs = make_arc(v1, v2, num_segs, num_segs + 1)
            points += ps
            faces += fs
        if 'a' in frame_elems:
            faces += [[len(points) + i, len(points) + i + 1]
                      for i in range(0, 6, 2)]
            points += [v0, -v0, v1, -v1, v2, -v2]

        rad = calc_polygons(pgon, 0, axis_angle, -1)[0][0].mag()
        points = [rad * p for p in points]
        faces += [[i] for i in range(len(points))]

    return points, faces
Пример #5
0
def j89_get_principal_verts(pgon, ang, flags):
    bad = flags.strip('ABC')
    if bad:
        raise ValueError('Unrecognised form flag(s) \'' + bad + '\'')
    ridge_down = 'A' in flags
    ridge2_down = 'B' in flags
    belt_back = 'C' in flags
    pgon.N *= 2
    # p_ang2 = pgon2.angle()
    A, B, B2, C = get_pstt_cap_verts(pgon, ang, ridge_down)
    pgon.N //= 2

    p_ang = pgon.angle() / 2
    A2_rad = pgon.circumradius(edge)  # circumradius of top polygon
    sq_mid = (B + B2) / 2
    sq_mid_rad = Vec(sq_mid[0], sq_mid[1], 0).mag()
    tri_ht2 = 3 / 4 - (A2_rad - sq_mid_rad)**2
    if tri_ht2 < -epsilon:
        raise ValueError(
            'Not possible to calculate upper equilateral triangle')

    A2_ht = (1 - 2 * belt_back) * sqrt(tri_ht2) + B[2]
    A2 = Vec(A2_rad, 0, A2_ht).rot_z(p_ang / 2)

    A2_minus1 = A2.rot_z(-2 * p_ang)
    B2_minus1 = B2.rot_z(-2 * p_ang)
    C2 = get_three_line_vert(A2_minus1, A2, B2_minus1, B, ridge2_down)
    return [pt.rot_z(p_ang / 2) for pt in [A, B, B2, C, A2, C2]]
Пример #6
0
def get_pstt_cap_verts(pgon, ang, ridge_down):
    p_ang = pgon.angle() / 2
    rad = pgon.circumradius(edge)

    # Polygon vertex
    A = Vec(rad, 0, 0)

    # First and last square vertices
    B = Vec(rad + edge * cos(ang) * cos(p_ang),
            edge * cos(ang) * sin(p_ang), edge * sin(ang))

    B2 = Vec(B[0], -B[1], B[2]).rot_z(2 * p_ang)

    A_minus1 = A.rot_z(-2 * p_ang)
    B2_minus1 = B2.rot_z(-4 * p_ang)
    C = get_three_line_vert(A, A_minus1, B, B2_minus1, ridge_down)

    return A, B, B2, C
Пример #7
0
def get_pstt_cap_verts(pgon, ang, ridge_down):
    p_ang = pgon.angle()/2
    rad = pgon.circumradius(edge)

    # Polygon vertex
    A = Vec(rad, 0, 0)

    # First and last square vertices
    B = Vec(rad + edge*cos(ang)*cos(p_ang),
            edge*cos(ang)*sin(p_ang),
            edge*sin(ang))

    B2 = Vec(B[0], -B[1], B[2]).rot_z(2*p_ang)

    A_minus1 = A.rot_z(-2*p_ang)
    B2_minus1 = B2.rot_z(-4*p_ang)
    C = get_three_line_vert(A, A_minus1, B, B2_minus1, ridge_down)

    return A, B, B2, C
Пример #8
0
def make_frame(frame_elems, pgon, axis_angle, num_segs):
    points = []
    faces = []
    if frame_elems:
        v0 = Vec(0, 0, 1)
        v1 = Vec(-math.sin(axis_angle), 0, math.cos(axis_angle))
        v2 = v1.rot_z(pgon.angle()/2)
        v2[2] *= -1
        if 'r' in frame_elems:
            ps, fs = make_arc(v0, v1, num_segs, 0)
            points += ps
            faces += fs
            ps, fs = make_arc(v1, v2, num_segs, num_segs+1)
            points += ps
            faces += fs
        if 'a' in frame_elems:
            faces += [[len(points)+i, len(points)+i+1] for i in range(0, 6, 2)]
            points += [v0, -v0, v1, -v1, v2, -v2]

        rad = calc_polygons(pgon, 0, axis_angle, -1)[0][0].mag()
        points = [rad * p for p in points]
        faces += [[i] for i in range(len(points))]

    return points, faces
Пример #9
0
def make_ring(R, N, a):
    b = ring_ball_ang(N, a)
    P = Vec(R * math.sin(a - b), 0, R * math.cos(a - b))
    return [P.rot_z(2 * math.pi * i / N) for i in range(N)], b
Пример #10
0
def cup_model(pgon, model_type):
    """Construct cupula model with golden trapziums"""
    ang = pgon.angle() / 2
    if model_type in ['0']:
        len_a, len_b, len_c = (phi - 1) / sin(math.pi / 2 - ang), 1, phi
    elif model_type in ['1', '2']:
        len_a, len_b, len_c = phi, 1, phi
    elif model_type in ['3']:
        len_a, len_b, len_c = phi, phi, 1
    ang = pgon.angle() / 2
    tan_a, r_a, R_a = get_belt_data(pgon, len_a, len_b)
    P = Vec(r_a, -len_a / 2, 0)
    Q = P + Vec(0, len_a, 0)
    points = []
    for i in range(pgon.N):
        points.append(P.rot_z(2 * i * ang))
        points.append(Q.rot_z(2 * i * ang))

    tan_b, r_b, R_b = get_belt_data(pgon, len_b, len_a)
    r_c = len_c / (2 * tan(ang))
    ht2 = gold_trap_ht**2 - (r_b - r_c)**2
    #  print(ht2, file=sys.stderr)
    if ht2 < -epsilon:
        raise ValueError('model is not constructible (height)')
    elif ht2 < 0:
        ht2 = 0
    ht = math.sqrt(ht2)
    R_c = len_c / (2 * sin(ang))
    V = Vec(R_c, 0, ht)
    N = pgon.N
    faces = []
    if model_type not in ['3']:
        faces.append([2 * N + i for i in range(N)])
    for i in range(pgon.N):
        points.append(V.rot_z(2 * i * ang))
    if model_type in ['0', '1']:
        faces.append([3 * N + i for i in range(N)])
        U = Vec(R_c, 0, -ht)
        for i in range(pgon.N):
            points.append(U.rot_z(2 * i * ang))
    elif model_type in ['3']:
        faces.append([i for i in range(2 * N)])

    for i in range(N):
        if model_type in ['0']:
            faces.append([2 * i, 3 * N + i, 2 * i + 1, 2 * N + i])
        else:
            faces.append([2 * i, 2 * i + 1, 2 * N + i])
        faces.append([
            2 * i + 1, (2 * i + 2) % (2 * N), 2 * N + ((i + 1) % N), 2 * N + i
        ])

    if model_type in ['0', '1']:
        for i in range(N):
            if model_type in ['1']:
                faces.append([2 * i, 2 * i + 1, 3 * N + i])
            faces.append([
                2 * i + 1, (2 * i + 2) % (2 * N), 3 * N + ((i + 1) % N),
                3 * N + i
            ])

    elif model_type in ['2']:
        belt_ht2 = gold_trap_ht**2 - (r_b - r_a)**2
        if belt_ht2 < -epsilon:
            raise ValueError('model is not constructible (belt height)')
        elif belt_ht2 < 0:
            belt_ht2 = 0
        belt_ht = math.sqrt(belt_ht2)
        for i, p in enumerate(points):
            points[i][2] += belt_ht / 2
        points += [Vec(p[0], p[1], -p[2]).rot_z(ang) for p in points]
        faces += [[idx + 3 * N for idx in f] for f in faces]
        for i in range(2 * N):
            faces.append([
                i, (i + 1) % (2 * N), 3 * N + i,
                3 * N + (2 * N + i - 1) % (2 * N)
            ])

    elif model_type in ['3']:
        for i, p in enumerate(points):
            points[i][2] -= ht
        points += [Vec(p[0], p[1], -p[2]) for p in points[:2 * N]]

        def new_v(v):
            v + 3 * N if v < 2 * N else v

        for i in range(len(faces)):
            faces.append([new_v(v) for v in faces[i]])

    return points, faces
Пример #11
0
def make_ring(R, N, a):
    b = ring_ball_ang(N, a)
    P = Vec(R*math.sin(a-b), 0, R*math.cos(a-b))
    return [P.rot_z(2*math.pi*i/N) for i in range(N)], b