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