-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmoth-goggles.py
84 lines (71 loc) · 2.74 KB
/
moth-goggles.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env python
import solid
import solid.utils as sutil
import numpy as np
# Output file settings
filename = "moth-goggles.scad"
SEGMENTS = 20
# Model settings
outer_sphere_radius = 35 # mm
inner_sphere_radius = 20 # mm
ommatidum_angle = 5 # deg
ommatidum_radius = np.tan(ommatidum_angle * np.pi / 180) * outer_sphere_radius
thickness = 0.25
def sph2cart(radius, azimuth, elevation):
"""Convert spherical coordinates to cartesian coordinates."""
x = radius * np.cos(elevation * np.pi / 180) * \
np.cos(azimuth * np.pi / 180)
y = radius * np.cos(elevation * np.pi / 180) * \
np.sin(azimuth * np.pi / 180)
z = radius * np.sin(elevation * np.pi / 180)
return x, y, z
def create_ommatidum(outer_sphere_radius,
inner_sphere_radius, ommatidum_radius):
"""Create an hexagonal based pyramid."""
# Outer shell
outer_shell = [tuple(np.round(sph2cart(ommatidum_radius, az, 0), 2))
for az in np.arange(0, 359, 60)]
outer_points = [[0, 0, 0]] + [[outer_sphere_radius, x, y]
for x, y, _ in outer_shell]
# Inner shell
inner_shell = [tuple(np.round(
sph2cart(ommatidum_radius - thickness, az, 0), 2))
for az in np.arange(0, 359, 60)]
inner_points = [[0, 0, 0]] + [[outer_sphere_radius, x, y]
for x, y, _ in inner_shell]
# Define Faces
faces = [
[0, 1, 2],
[0, 2, 3],
[0, 3, 4],
[0, 4, 5],
[0, 5, 6],
[0, 6, 1],
[1, 2, 3, 4, 5, 6]]
# Create ommatidum
ommatidum = solid.difference()(
solid.hull()(solid.polyhedron(outer_points, faces)),
solid.hull()(solid.polyhedron(inner_points, faces)),
solid.sphere(inner_sphere_radius)
)
return ommatidum
def create_moth_eye(ommatidum, ommatidum_radius, sphere_radius):
"""Create moth eye using ommatidia."""
# Elevation angle correction
el_step = np.arctan2(
ommatidum_radius * np.cos(30.0 * np.pi / 180.0),
sphere_radius) * 180 / np.pi
elevation = np.arange(-45, 45, 2 * (el_step))
moth_eye = solid.union()
for el in elevation:
curr_radius = sphere_radius * np.cos(el * np.pi / 180)
az_step = np.arctan2(ommatidum_radius, curr_radius) * 180 / np.pi
azimuth = np.arange(0, 180, 2 * az_step)
for az in azimuth:
moth_eye.add(solid.rotate([0, el, az])(ommatidum))
return moth_eye
ommatidum = create_ommatidum(outer_sphere_radius,
inner_sphere_radius, ommatidum_radius)
moth_eye = create_moth_eye(ommatidum, ommatidum_radius, outer_sphere_radius)
solid.scad_render_to_file(moth_eye, filename,
file_header='$fn = %s;' % SEGMENTS)