예제 #1
0
def generate_octahedra():
    view = create_lookat(eye=[-15, -60, 120], target=[0, 0, 0], up=[0, 1, 0])
    projection = create_perspective(fovy=15, aspect=1, near=10, far=200)
    camera = svg3d.Camera(view, projection)

    verts, faces = icosahedron()
    verts, faces = np.float32(verts), np.uint32(faces)
    faces = 15 * verts[faces]

    centroids = []
    for face in faces:
        centroid = np.float32([0, 0, 0])
        for vert in face:
            centroid += vert
        centroid /= len(face)
        centroids.append(centroid)
    centroids = np.float32([centroids])

    point_style = dict(fill="black", fill_opacity="0.75", stroke="none")
    poly_style = dict(
        fill="#f0f0f0",
        fill_opacity="0.75",
        stroke="black",
        stroke_linejoin="round",
        stroke_width="0.01",
    )

    left_viewport = svg3d.Viewport.from_string("-1.0 -0.5 1.0 1.0")
    right_viewport = svg3d.Viewport.from_string("0.0 -0.5 1.0 1.0")

    back_shader = lambda face_index, winding: None if winding >= 0 else poly_style
    front_shader = lambda face_index, winding: None if winding < 0 else poly_style

    two_pass_scene = svg3d.Scene([])
    two_pass_scene.add_mesh(svg3d.Mesh(faces, back_shader))
    two_pass_scene.add_mesh(svg3d.Mesh(faces, front_shader))
    two_pass_scene.add_mesh(
        svg3d.Mesh(centroids, style=point_style, circle_radius=0.005)
    )

    one_pass_scene = svg3d.Scene([])
    one_pass_scene.add_mesh(svg3d.Mesh(faces, style=poly_style))
    one_pass_scene.add_mesh(
        svg3d.Mesh(centroids, style=point_style, circle_radius=0.005)
    )

    view0 = svg3d.View(camera, one_pass_scene, left_viewport)
    view1 = svg3d.View(camera, two_pass_scene, right_viewport)

    svg3d.Engine([view0, view1]).render(
        "octahedra.svg", (512, 256), "-1.0 -0.5 2.0 1.0"
    )
예제 #2
0
def capsule():
    verts, indices = octasphere(ndivisions=3,
                                radius=4,
                                width=18,
                                height=0,
                                depth=0)
    view_matrix = create_lookat(eye=[25, 20, 60],
                                target=[0, 0, 0],
                                up=[0, 1, 0])
    faces = verts[indices]
    ones = np.ones(faces.shape[:2] + (1, ))
    eyespace_faces = np.dstack([faces, ones])
    eyespace_faces = np.dot(eyespace_faces, view_matrix)[:, :, :3]
    L = pyrr.vector.normalize(np.float32([20, 20, 50]))
    E = np.float32([0, 0, 1])
    H = pyrr.vector.normalize(L + E)

    def frontface_shader(face_index, winding):
        if winding < 0:
            return None
        face = eyespace_faces[face_index]
        p0, p1, p2 = face[0], face[1], face[2]
        N = pyrr.vector3.cross(p1 - p0, p2 - p0)
        l2 = pyrr.vector3.squared_length(N)
        if l2 > 0:
            N = N / np.sqrt(l2)
        df = max(0, np.dot(N, L))
        sf = pow(max(0, np.dot(N, H)), SHININESS)
        color = df * DIFFUSE + sf * SPECULAR
        color = np.power(color, 1.0 / 2.2)
        return dict(fill=rgb(*color), stroke="black", stroke_width="0.001")

    return svg3d.Mesh(faces, frontface_shader)
예제 #3
0
def create_surface_plot():

    divs = 25

    X, Y = np.meshgrid(np.linspace(-2, 2, divs), np.linspace(-2, 2, divs))
    Z = 2 * X * np.exp(-X * X - Y * Y)
    verts = np.reshape(np.dstack([X, Y, Z]), [divs * divs, 3])

    i, j = np.mgrid[0 : divs * 2, 0 : divs * 2]
    coords = np.uint32(np.dstack([i / 2, j / 2]))
    coords = coords[1 : divs * 2 - 1, 1 : divs * 2 - 1]
    indices = coords[:, :, 0] * divs + coords[:, :, 1]
    nw = indices[0::2][:, 0::2]
    ne = indices[0::2][:, 1::2]
    sw = indices[1::2][:, 0::2]
    se = indices[1::2][:, 1::2]
    indices = np.dstack([nw, ne, se, sw])
    indices = np.reshape(indices, [(divs - 1) * (divs - 1), 4])
    faces = verts[indices]

    view = create_lookat(eye=[5, 20, 5], target=[0, 0, 0], up=[0, 0, 1])
    projection = create_perspective(fovy=15, aspect=1, near=1, far=100)
    camera = svg3d.Camera(view, projection)

    style = dict(
        fill="#f0f0f0",
        fill_opacity="0.75",
        stroke="black",
        stroke_linejoin="round",
        stroke_width="0.001",
    )

    rgb = apply_turbo_colormap(Z)
    colors = np.reshape(rgb, [divs * divs, 3])
    colors = colors[indices]

    def shader(face_index, winding):
        face_colors = colors[face_index]
        rgb = ",".join([str(int(num * 255)) for num in face_colors[0]])
        style["fill"] = f"rgb({rgb})"
        return style

    scene = svg3d.Scene([svg3d.Mesh(faces, shader)])
    view = svg3d.View(camera, scene)
    svg3d.Engine([view]).render("plot.svg")
예제 #4
0
def make_octaspheres(ndivisions: int,
                     radius: float,
                     width=0,
                     height=0,
                     depth=0):
    verts, indices = octasphere(ndivisions, radius, width, height, depth)
    faces = verts[indices]

    left = translate_faces(faces, [-12, 0, 0])
    right = translate_faces(rotate_faces(faces), [12, 0, 0])
    faces = merge_faces(left, right)

    ones = np.ones(faces.shape[:2] + (1, ))
    eyespace_faces = np.dstack([faces, ones])
    eyespace_faces = np.dot(eyespace_faces, view_matrix)[:, :, :3]
    L = pyrr.vector.normalize(np.float32([20, 20, 50]))
    E = np.float32([0, 0, 1])
    H = pyrr.vector.normalize(L + E)

    def frontface_shader(face_index, winding):
        if winding < 0:
            return None
        face = eyespace_faces[face_index]
        p0, p1, p2 = face[0], face[1], face[2]
        N = pyrr.vector3.cross(p1 - p0, p2 - p0)
        l2 = pyrr.vector3.squared_length(N)
        if l2 > 0:
            N = N / np.sqrt(l2)
        df = max(0, np.dot(N, L))
        sf = pow(max(0, np.dot(N, H)), SHININESS)
        color = df * DIFFUSE + sf * SPECULAR
        color = np.power(color, 1.0 / 2.2)
        return dict(fill=rgb(*color), stroke="black", stroke_width="0.001")

    print(
        f"Generated octasphere: {ndivisions}, {radius}, {width}, {height}, {depth}"
    )
    return [svg3d.Mesh(faces, frontface_shader)]
예제 #5
0
def generate_overlapping_triangles():
    X = 1
    Y = 2

    view = create_lookat(eye=[1.5, 1.5, 5], target=[1.5, 1.5, 0], up=[0, 1, 0])
    projection = create_ortho(-X, X, -Y, Y, 0, 10)
    pick = pyrr.matrix44.create_from_translation([1, 0, 0])
    left_camera = svg3d.Camera(view, np.dot(projection, pick))

    projection = create_ortho(-X, X, -Y, Y, 0, 10)
    pick = pyrr.matrix44.create_from_translation([-1, 0, 0])
    right_camera = svg3d.Camera(view, np.dot(pick, projection))

    z0 = 0.00
    z1 = 0.01
    z2 = 0.02
    z3 = -0.03

    faces = np.float32(
        [
            [(0, 0, z0), (1, 0, z0), (0.5, 3, z0)],
            [(0, 2, z1), (0, 3, z1), (3, 2.5, z1)],
            [(2, 3, z2), (3, 3, z2), (2.5, 0, z2)],
            [(3, 0, z3), (3, 1, z3), (0, 0.5, z3)],
        ]
    )

    poly_style = dict(
        fill="#e0e0e0",
        fill_opacity="0.75",
        stroke="black",
        stroke_linejoin="round",
        stroke_width="0.01",
    )
    left_scene = svg3d.Scene([svg3d.Mesh(faces, style=poly_style)])
    left_view = svg3d.View(
        left_camera, left_scene, svg3d.Viewport.from_string("-.5 -.5 .5 1")
    )

    z3 = 0.03

    faces = np.float32(
        [
            [(0, 0, z0), (1, 0, z0), (0.5, 3, z0)],
            [(0, 2, z1), (0, 3, z1), (3, 2.5, z1)],
            [(2, 3, z2), (3, 3, z2), (2.5, 0, z2)],
            [(3, 0, z3), (3, 1, z3), (0, 0.5, z3)],
        ]
    )

    poly_style = dict(
        fill="#e0e0e0",
        fill_opacity="0.75",
        stroke="black",
        stroke_linejoin="round",
        stroke_width="0.01",
    )
    right_scene = svg3d.Scene([svg3d.Mesh(faces, style=poly_style)])
    right_view = svg3d.View(
        right_camera, right_scene, svg3d.Viewport.from_string("0 -.5 .5 1")
    )

    svg3d.Engine([left_view, right_view]).render("overlapping_triangles.svg")
예제 #6
0
def create_complex_shapes():
    projection = create_perspective(fovy=25, aspect=1, near=10, far=200)
    view = create_lookat(eye=[25, 20, 60], target=[0, 0, 0], up=[0, 1, 0])
    camera = svg3d.Camera(view, projection)

    # Parametric Sphere

    slices, stacks, radius = 64, 64, 12
    faces = radius * parametric_surface(slices, stacks, sphere)

    antialiasing = "auto"  # use 'crispEdges' to fix cracks

    def shader(face_index, winding):
        slice = int(face_index / 64)
        stack = int(face_index % 64)
        if slice % 3 == 0 or stack % 3 == 0:
            return dict(
                fill="black",
                fill_opacity="1.0",
                stroke="none",
                shape_rendering=antialiasing,
            )
        return dict(
            fill="white",
            fill_opacity="0.75",
            stroke="none",
            shape_rendering=antialiasing,
        )

    scene = svg3d.Scene([svg3d.Mesh(faces, shader)])
    svg3d.Engine([svg3d.View(camera, scene)]).render("parametric_sphere.svg")

    # Sphere Shell

    verts, faces = icosahedron()
    verts, faces = subdivide(verts, faces)
    verts, faces = subdivide(verts, faces)
    verts, faces = np.float32(verts), np.int32(faces)
    faces = verts[faces]

    def backface_shader(face_index, winding):
        if winding >= 0:
            return None
        return dict(
            fill="#7f7fff",
            fill_opacity="1.0",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.001",
            stroke_dasharray="0.01",
        )

    def frontface_shader(face_index, winding):
        if winding < 0 or faces[face_index][0][2] > 0.9:
            return None
        return dict(
            fill="#7fff7f",
            fill_opacity="0.6",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.003",
        )

    scene = svg3d.Scene([])
    scene.add_mesh(svg3d.Mesh(12.0 * faces, backface_shader))
    scene.add_mesh(svg3d.Mesh(12.0 * faces, frontface_shader))
    svg3d.Engine([svg3d.View(camera, scene)]).render("sphere_shell.svg")

    # Sphere Lighting

    ones = np.ones(faces.shape[:2] + (1,))
    eyespace_faces = np.dstack([faces, ones])
    eyespace_faces = np.dot(eyespace_faces, view)[:, :, :3]
    shininess = 100
    L = pyrr.vector.normalize(np.float32([20, 20, 50]))
    E = np.float32([0, 0, 1])
    H = pyrr.vector.normalize(L + E)

    def frontface_shader(face_index, winding):
        if winding < 0:
            return None
        face = eyespace_faces[face_index]
        p0, p1, p2 = face[0], face[1], face[2]
        N = pyrr.vector.normalize(pyrr.vector3.cross(p1 - p0, p2 - p0))
        df = max(0, np.dot(N, L))
        sf = pow(max(0, np.dot(N, H)), shininess)
        color = df * np.float32([1, 1, 0]) + sf * np.float32([1, 1, 1])
        color = np.power(color, 1.0 / 2.2)
        return dict(
            fill=rgb(*color), fill_opacity="1.0", stroke="black", stroke_width="0.001"
        )

    scene = svg3d.Scene([])
    scene.add_mesh(svg3d.Mesh(12.0 * faces, frontface_shader))
    svg3d.Engine([svg3d.View(camera, scene)]).render("sphere_lighting.svg")

    # Mobius Tube

    slices, stacks, radius = 48, 32, 7
    faces = radius * parametric_surface(slices, stacks, mobius_tube)

    ones = np.ones(faces.shape[:2] + (1,))
    eyespace_faces = np.dstack([faces, ones])
    eyespace_faces = np.dot(eyespace_faces, view)[:, :, :3]
    shininess = 75
    L = pyrr.vector.normalize(np.float32([10, -10, 50]))
    E = np.float32([0, 0, 1])
    H = pyrr.vector.normalize(L + E)

    def frontface_shader(face_index, winding):
        if winding < 0:
            return None
        face = eyespace_faces[face_index]
        p0, p1, p2 = face[0], face[1], face[2]
        N = pyrr.vector.normalize(pyrr.vector3.cross(p1 - p0, p2 - p0))
        df = max(0, np.dot(N, L))
        sf = pow(max(0, np.dot(N, H)), shininess)
        color = df * np.float32([0, 0.8, 1]) + sf * np.float32([1, 1, 1])
        color = np.power(color, 1.0 / 2.2)
        return dict(
            fill=rgb(*color),
            fill_opacity="1.0",
            stroke=rgb(*(color * 1.5)),
            stroke_width="0.001",
        )

    scene = svg3d.Scene([])
    scene.add_mesh(svg3d.Mesh(faces, frontface_shader))
    svg3d.Engine([svg3d.View(camera, scene)]).render("mobius_tube.svg")

    # Filmstrip

    def shader(face_index, winding):
        return dict(
            fill="white",
            fill_opacity="0.75",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.005",
        )

    thin = dict(
        fill="white",
        fill_opacity="0.75",
        stroke="black",
        stroke_linejoin="round",
        stroke_width="0.001",
    )

    view = create_lookat(eye=[50, 40, 120], target=[0, 0, 0], up=[0, 1, 0])
    projection = create_perspective(fovy=15, aspect=1, near=10, far=200)
    camera = svg3d.Camera(view, projection)

    viewport0 = svg3d.Viewport.from_string("-2.5 -0.5 1.0 1.0")
    viewport1 = svg3d.Viewport.from_string("-1.5 -0.5 1.0 1.0")
    viewport2 = svg3d.Viewport.from_string("-0.5 -0.5 1.0 1.0")
    viewport3 = svg3d.Viewport.from_string(" 0.5 -0.5 1.0 1.0")
    viewport4 = svg3d.Viewport.from_string(" 1.5 -0.5 1.0 1.0")

    slices, stacks = 24, 32
    sphere_faces = 15.0 * parametric_surface(slices, stacks, sphere)

    slices, stacks = 32, 24
    klein_faces = 3.0 * parametric_surface(slices, stacks, klein)

    slices, stacks, radius = 48, 32, 7
    mobius_faces = radius * parametric_surface(slices, stacks, mobius_tube)

    # cube
    view0 = svg3d.View(camera, svg3d.Scene([svg3d.Mesh(cube(), shader)]), viewport0)

    # octahedron
    view1 = svg3d.View(
        camera, svg3d.Scene([svg3d.Mesh(12.0 * octahedron(), shader)]), viewport1
    )

    # sphere
    view2 = svg3d.View(
        camera, svg3d.Scene([svg3d.Mesh(sphere_faces, style=thin)]), viewport2
    )

    # klein
    klein_view = create_lookat(eye=[50, 120, 50], target=[0, 0, 0], up=[0, 0, 1])
    klein_projection = create_perspective(fovy=28, aspect=1, near=10, far=200)
    klein_camera = svg3d.Camera(klein_view, klein_projection)
    view3 = svg3d.View(
        klein_camera, svg3d.Scene([svg3d.Mesh(klein_faces, style=thin)]), viewport3
    )

    # mobius
    view4 = svg3d.View(
        camera, svg3d.Scene([svg3d.Mesh(mobius_faces, frontface_shader)]), viewport4
    )

    drawing = svgwrite.Drawing(
        "filmstrip.svg", (256 * 5, 256), viewBox="-2.5 -0.5 5.0 1.0"
    )
    svg3d.Engine([view0, view1, view2, view3, view4]).render_to_drawing(drawing)
    drawing.save()
예제 #7
0
def create_simple_shapes():
    view = create_lookat(eye=[50, 40, 120], target=[0, 0, 0], up=[0, 1, 0])
    projection = create_perspective(fovy=15, aspect=1, near=10, far=200)
    camera = svg3d.Camera(view, projection)
    thin_style = dict(
        fill="white",
        stroke="black",
        stroke_linejoin="round",
        fill_opacity="0.75",
        stroke_width="0.002",
    )
    thick_style = dict(
        fill="white",
        stroke="black",
        stroke_linejoin="round",
        fill_opacity="0.75",
        stroke_width="0.005",
    )

    left_viewport = svg3d.Viewport.from_string("-1.0 -0.5 1.0 1.0")
    right_viewport = svg3d.Viewport.from_string("0.0 -0.5 1.0 1.0")

    # Octahedron

    style = dict(
        fill="white",
        fill_opacity="0.75",
        stroke="black",
        stroke_linejoin="round",
        stroke_width="0.005",
    )
    mesh = svg3d.Mesh(15.0 * octahedron(), style=style)
    view = svg3d.View(camera, svg3d.Scene([mesh]))
    svg3d.Engine([view]).render("octahedron.svg")

    # Sphere and Klein

    def shader(face_index, winding):
        return dict(
            fill="white",
            fill_opacity="0.75",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.002",
        )

    slices, stacks = 32, 32
    faces = 15.0 * parametric_surface(slices, stacks, sphere)
    sphere_view = svg3d.View(
        camera, svg3d.Scene([svg3d.Mesh(faces, shader)]), left_viewport
    )

    klein_view = create_lookat(eye=[50, 120, 50], target=[0, 0, 0], up=[0, 0, 1])
    klein_projection = create_perspective(fovy=28, aspect=1, near=10, far=200)
    klein_camera = svg3d.Camera(klein_view, klein_projection)

    faces = 3.0 * parametric_surface(slices, stacks, klein)
    klein_view = svg3d.View(
        klein_camera, svg3d.Scene([svg3d.Mesh(faces, shader)]), right_viewport
    )

    svg3d.Engine([sphere_view, klein_view]).render(
        "sphere_and_klein.svg", (512, 256), "-1.0 -0.5 2.0 1.0"
    )
예제 #8
0
파일: platonic.py 프로젝트: prideout/svg3d
def create_octahedron_pair(filename):
    vp = svg3d.Viewport.from_aspect(2)
    projection = create_perspective(fovy=25, aspect=2, near=10, far=200)
    view = create_lookat(eye=[0, 20, 60], target=[0, 0, 0], up=[0, 1, 0])
    camera = svg3d.Camera(view, projection)

    scene = svg3d.Scene([])

    faces = octahedron()
    def backface_shader(face_index, winding):
        if winding >= 0: return None
        return dict(
            fill="#7f7fff",
            fill_opacity="1.0",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.002",
            stroke_dasharray="0.01",
        )
    def frontface_shader(face_index, winding):
        if winding < 0: return None
        return dict(
            fill="#7fff7f",
            fill_opacity="0.4",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.003",
        )
    faces += np.array([-1.25, 0, 0])
    scene.add_mesh(svg3d.Mesh(12.0 * faces, backface_shader))
    scene.add_mesh(svg3d.Mesh(12.0 * faces, frontface_shader))

    faces2 = hexahedron() * 0.8
    def backface_shader2(face_index, winding):
        if winding >= 0: return None
        return dict(
            fill="#7f7fff",
            fill_opacity="1.0",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.002",
            stroke_dasharray="0.01",
        )
    def frontface_shader2(face_index, winding):
        if winding < 0: return None
        return dict(
            fill="#7fff7f",
            fill_opacity="0.4",
            stroke="black",
            stroke_linejoin="round",
            stroke_width="0.003",
        )

    q = quaternion.create_from_eulers([0, pi * 0.25, 0])
    for f in faces2:
        for v in f:
            v[:] = quaternion.apply_to_vector(q, v)

    faces2 += np.array([12.0, 0, 0])
    scene.add_mesh(svg3d.Mesh(faces2, backface_shader2))
    scene.add_mesh(svg3d.Mesh(faces2, frontface_shader2))

    e = svg3d.Engine([svg3d.View(camera, scene, vp)])
    e.render(filename, (1024, 512))