cosplay: Touhou/Shiki Eiki #7
|
@ -10,9 +10,9 @@ class Crown(Model):
|
|||
|
||||
facets: int = 5
|
||||
# Lower circumference
|
||||
base_circ: float = 570.0
|
||||
base_circ: float = 538.0
|
||||
# Upper circumference
|
||||
tilt_circ: float = 670.0
|
||||
tilt_circ: float = 640.0
|
||||
height: float = 120.0
|
||||
|
||||
margin: float = 10.0
|
||||
|
@ -25,6 +25,7 @@ class Crown(Model):
|
|||
super().__init__(name="crown")
|
||||
|
||||
assert self.tilt_circ > self.base_circ
|
||||
assert self.facet_width_upper / 2 > self.height / 2, "Top angle must be > 90 degrees"
|
||||
|
||||
@property
|
||||
def facet_width_lower(self):
|
||||
|
@ -33,8 +34,7 @@ class Crown(Model):
|
|||
def facet_width_upper(self):
|
||||
return self.tilt_circ / self.facets
|
||||
|
||||
@target(name="side", kind=TargetKind.DXF)
|
||||
def profile_side(self) -> Cq.Sketch:
|
||||
def profile_base(self) -> Cq.Sketch:
|
||||
# Generate the pentagonal shape
|
||||
|
||||
dx_l = self.facet_width_lower
|
||||
|
@ -51,6 +51,35 @@ class Crown(Model):
|
|||
])
|
||||
)
|
||||
|
||||
@target(name="side", kind=TargetKind.DXF)
|
||||
def profile_side(self) -> Cq.Sketch:
|
||||
dy = self.facet_width_upper * 0.1
|
||||
x_side = self.facet_width_upper
|
||||
y_tip = self.height - self.margin
|
||||
|
||||
eye = (
|
||||
Cq.Sketch()
|
||||
.segment(
|
||||
(0, y_tip),
|
||||
(dy, y_tip - dy),
|
||||
)
|
||||
.segment(
|
||||
(0, y_tip),
|
||||
(-dy, y_tip - dy),
|
||||
)
|
||||
.bezier([
|
||||
(dy, y_tip - dy),
|
||||
(0, y_tip - dy/2),
|
||||
(0, y_tip - dy/2),
|
||||
(-dy, y_tip - dy),
|
||||
])
|
||||
.assemble()
|
||||
)
|
||||
return (
|
||||
self.profile_base()
|
||||
.boolean(eye, mode='s')
|
||||
)
|
||||
|
||||
@target(name="dot", kind=TargetKind.DXF)
|
||||
def profile_dot(self) -> Cq.Sketch:
|
||||
return (
|
||||
|
@ -72,7 +101,7 @@ class Crown(Model):
|
|||
)
|
||||
window_p1 = Cq.Location.from2d(
|
||||
dx_u/2 - self.margin - window_length * 0.4,
|
||||
dy/2 + self.margin,
|
||||
dy/2 + self.margin/2,
|
||||
math.degrees(math.atan2(dy/2, -dx_u/2)),
|
||||
)
|
||||
window_p2 = Cq.Location.from2d(
|
||||
|
@ -156,20 +185,44 @@ class Crown(Model):
|
|||
needle_y_top = dy - self.margin
|
||||
needle_y_mid = dy * 0.7
|
||||
needle_dx = scale_base_x * 2
|
||||
y_shoulder = needle_y_mid - z * 2
|
||||
needle = (
|
||||
Cq.Sketch()
|
||||
.segment(
|
||||
(0, needle_y_mid),
|
||||
(z, y_shoulder),
|
||||
)
|
||||
.segment(
|
||||
(z, y_shoulder),
|
||||
(z, scale_base_y),
|
||||
)
|
||||
.segment(
|
||||
(z, scale_base_y),
|
||||
(-z, scale_base_y),
|
||||
)
|
||||
.segment(
|
||||
(-z, y_shoulder),
|
||||
(-z, scale_base_y),
|
||||
)
|
||||
.segment(
|
||||
(-z, y_shoulder),
|
||||
(0, needle_y_mid),
|
||||
)
|
||||
.assemble()
|
||||
)
|
||||
z2 = z * 2
|
||||
y1 = needle_y_mid + z2
|
||||
needle_head = (
|
||||
Cq.Sketch()
|
||||
.segment(
|
||||
(z, needle_y_mid),
|
||||
(z, scale_base_y),
|
||||
(z, y1),
|
||||
)
|
||||
.segment(
|
||||
(z, scale_base_y),
|
||||
(-z, scale_base_y),
|
||||
)
|
||||
.segment(
|
||||
(-z, scale_base_y),
|
||||
(-z, needle_y_mid),
|
||||
(-z, y1),
|
||||
)
|
||||
# Outer edge
|
||||
.bezier([
|
||||
(0, needle_y_top),
|
||||
(0, (needle_y_top + needle_y_mid)/2),
|
||||
|
@ -182,40 +235,24 @@ class Crown(Model):
|
|||
(-needle_dx, (needle_y_top + needle_y_mid)/2),
|
||||
(-z, needle_y_mid),
|
||||
])
|
||||
.assemble()
|
||||
)
|
||||
z2 = z * 2
|
||||
needle_inner = (
|
||||
Cq.Sketch()
|
||||
.segment(
|
||||
(z2, needle_y_mid - z2),
|
||||
(-z2, needle_y_mid - z2)
|
||||
)
|
||||
.segment(
|
||||
(z2, needle_y_mid - z2),
|
||||
(z2, needle_y_mid + z2),
|
||||
)
|
||||
.segment(
|
||||
(-z2, needle_y_mid - z2),
|
||||
(-z2, needle_y_mid + z2),
|
||||
)
|
||||
# Inner edge
|
||||
.bezier([
|
||||
(0, needle_y_top - z2),
|
||||
(0, (needle_y_top + needle_y_mid)/2),
|
||||
(needle_dx-z2*2, (needle_y_top + needle_y_mid)/2),
|
||||
(z2, needle_y_mid + z2),
|
||||
(z, y1),
|
||||
])
|
||||
.bezier([
|
||||
(0, needle_y_top - z2),
|
||||
(0, (needle_y_top + needle_y_mid)/2),
|
||||
(-needle_dx+z2*2, (needle_y_top + needle_y_mid)/2),
|
||||
(-z2, needle_y_mid + z2),
|
||||
(-z, y1),
|
||||
])
|
||||
.assemble()
|
||||
)
|
||||
|
||||
return (
|
||||
self.profile_side()
|
||||
self.profile_base()
|
||||
.boolean(window.moved(window_p1), mode='s')
|
||||
.boolean(window.moved(window_p1.flip_x()), mode='s')
|
||||
.boolean(window.moved(window_p2), mode='s')
|
||||
|
@ -224,7 +261,7 @@ class Crown(Model):
|
|||
.boolean(scale_pan.moved(loc_scale_pan2), mode='s')
|
||||
.boolean(scale_body, mode='s')
|
||||
.boolean(needle, mode='s')
|
||||
.boolean(needle_inner, mode='a')
|
||||
.boolean(needle_head, mode='s')
|
||||
.clean()
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue