extern crate lux;
extern crate implicit;
mod helper;
mod display;
use implicit::*;
use implicit::geom::*;
const DASH_SIZE_ON: f32 = 7.0;
const DASH_SIZE_OFF: f32 = 10.0;
const NECK_CIRC: f32 = 1250.0;
const MAIN_HEIGHT: f32 = 100.0;
const FRONT_LEN: f32 = NECK_CIRC * (3.0 / 4.0);
const TRI_OFFSET: f32 = 50.0;
const BACK_LEN: f32 = NECK_CIRC * (3.0 / 4.0);
const HOLE_RADIUS: f32 = 12.5;
const HOLE_SPACING: f32 = HOLE_RADIUS * 4.0;
const HOLE_OFFSET: f32 = 50.0;
const STITCH_OFFSET: f32 = 10.0;
const NUM_HOLES: i32 = 5;
const CENTER_LEN: f32 = FRONT_LEN * (1.0 / 3.0);
const CENTER_HEIGHT: f32 = MAIN_HEIGHT * (1.0 + 1.0 / 4.0);
const CENTER_SHIFT_DOWN: f32 = MAIN_HEIGHT * (1.0 / 4.0);
const HOOK_CHUNK_HEIGHT: f32 = (CENTER_HEIGHT + CENTER_SHIFT_DOWN) / 4.0;
const HOOK_TOTAL_LEN: f32 = 300.0;
const HOOK_MIDDLE_LEN: f32 = 128.0;
const HOOK_ATTACH_SPACING: f32 = 51.5;
const HOOK_BASE_SPACING: f32 = 20.0;
fn front_outline() -> PolyGroup {
let main_front_rect = Rectangle::new(Rect::from_points(
&Point {x: 0.0, y: 0.0},
&Point {x: FRONT_LEN, y: MAIN_HEIGHT}));
let left_triangle = Polygon::new(vec![
Point { x: -TRI_OFFSET, y: MAIN_HEIGHT / 2.0 },
Point { x: 0.0, y: 0.0 },
Point { x: 0.0, y: MAIN_HEIGHT }].into_iter());
let right_triangle = Polygon::new(vec![
Point { x: FRONT_LEN + TRI_OFFSET, y: MAIN_HEIGHT / 2.0 },
Point { x: FRONT_LEN, y: 0.0 },
Point { x: FRONT_LEN, y: MAIN_HEIGHT }].into_iter());
let result = main_front_rect.or(left_triangle).or(right_triangle);
result.fix_rules(2.25)
}
fn holes() -> Vec<Not<Circle>> {
let mut holes = vec![];
for i in 0 .. NUM_HOLES {
holes.push(
Circle {
center: Point {
x: FRONT_LEN - HOLE_OFFSET - HOLE_SPACING * i as f32,
y: MAIN_HEIGHT / 2.0
},
radius: HOLE_RADIUS
}.not());
holes.push(
Circle {
center: Point {
x: HOLE_OFFSET + HOLE_SPACING * i as f32,
y: MAIN_HEIGHT / 2.0
},
radius: HOLE_RADIUS
}.not());
}
holes
}
fn center() -> PolyGroup {
let block = Rectangle::new(Rect::from_points(
&Point {x: 0.0, y: 0.0},
&Point {x: CENTER_LEN, y: CENTER_HEIGHT}));
let left_triangle = Polygon::new(vec![
Point { x: -TRI_OFFSET, y: CENTER_HEIGHT / 2.0 },
Point { x: 0.0, y: 0.0 },
Point { x: 0.0, y: CENTER_HEIGHT }].into_iter());
let right_triangle = Polygon::new(vec![
Point { x: CENTER_LEN + TRI_OFFSET, y: CENTER_HEIGHT / 2.0 },
Point { x: CENTER_LEN, y: 0.0 },
Point { x: CENTER_LEN, y: CENTER_HEIGHT }].into_iter());
let result = block.or(left_triangle).or(right_triangle).translate(TRI_OFFSET, 0.0);
result.fix_rules(2.25)
}
fn front() -> AndThese<SyncBox> {
let front_outline = front_outline(); let center = center();
let center = center.center_at(&front_outline.center().unwrap());
let center = center.translate(0.0, CENTER_SHIFT_DOWN);
let front_collar = front_outline.or(center);
let mut targets: Vec<SyncBox> = holes().into_iter().map(|a| a.boxed()).collect();
targets.push(front_collar.clone().boxed());
AndThese { targets: targets }
}
fn back() -> SyncBox {
let back_outline = Rectangle::new(Rect::from_points(
&Point {x: 0.0, y: 0.0},
&Point {x: BACK_LEN, y: MAIN_HEIGHT}));
let center = center();
let center = center.center_at(&back_outline.center().unwrap());
let center = center.translate(0.0, CENTER_SHIFT_DOWN);
let back_collar = back_outline.or(center);
back_collar.boxed()
}
fn hook_attach(middle_height: f32) -> Or<Or<Rectangle, Rectangle>, Rectangle> {
let mid = Rectangle::new(Rect::from_point_and_size(
&Point{x: (HOOK_TOTAL_LEN - HOOK_MIDDLE_LEN) / 2.0, y: HOOK_CHUNK_HEIGHT},
&Vector{x: HOOK_MIDDLE_LEN, y: middle_height}));
hook_attach_stitch(middle_height).or(mid)
}
fn hook_attach_stitch(middle_height: f32) -> Or<Rectangle, Rectangle> {
let top = Rectangle::new(Rect::from_point_and_size(
&Point{x: 0.0, y: 0.0},
&Vector{x: HOOK_TOTAL_LEN, y: HOOK_CHUNK_HEIGHT}));
let bot = Rectangle::new(Rect::from_point_and_size(
&Point{x: 0.0, y: middle_height + HOOK_CHUNK_HEIGHT},
&Vector{x: HOOK_TOTAL_LEN, y: HOOK_CHUNK_HEIGHT}));
top.or(bot)
}
fn main() {
fn offset(y: f32) -> Matrix {
Matrix::new().translate(50.0, y)
}
let front_collar = front();
let front_collar_outline = front_collar.clone().shrink(STITCH_OFFSET);
let back_collar = back();
let back_collar_outline = back_collar.clone().shrink(STITCH_OFFSET);
let hook_attach_stitched = hook_attach_stitch(HOOK_BASE_SPACING).shrink(STITCH_OFFSET);
let hook_attach_stitched = hook_attach_stitched.center_at(&front_collar.center().unwrap());
let mut scene = Scene::new();
scene.resolution = 0.5;
let offset_50 = offset(0.0);
let offset_250 = offset(200.0);
let offset_450 = offset(400.0);
let offset_650 = offset(600.0);
let offset_850 = offset(800.0);
let offset_850_right = offset_850.translate(400.0, 0.0);
let center = front_collar.bounding_box().unwrap().midpoint();
let f_c = scene.add_shape(&front_collar, RenderMode::Outline, offset_50);
let f_o = scene.add_shape(&front_collar_outline, RenderMode::DashedPerfect(vec![DASH_SIZE_ON, DASH_SIZE_OFF]), offset_50);
scene.add_shape(&hook_attach_stitched, RenderMode::DashedPerfect(vec![DASH_SIZE_ON, DASH_SIZE_OFF]), offset_50);
scene.add_again(f_c, offset_250.mirror_horizontal(center.x));
scene.add_again(f_o, offset_250.mirror_horizontal(center.x));
let b_c = scene.add_shape(&back_collar, RenderMode::Outline, offset_450);
let b_o = scene.add_shape(&back_collar_outline, RenderMode::DashedPerfect(vec![DASH_SIZE_ON, DASH_SIZE_OFF]), offset_450);
scene.add_shape(&hook_attach_stitched, RenderMode::DashedPerfect(vec![DASH_SIZE_ON, DASH_SIZE_OFF]), offset_450);
scene.add_again(b_c, offset_650.mirror_horizontal(center.x));
scene.add_again(b_o, offset_650.mirror_horizontal(center.x));
let hook_attach = hook_attach(HOOK_ATTACH_SPACING);
let hook_attach_stitch = hook_attach_stitch(HOOK_ATTACH_SPACING).shrink(STITCH_OFFSET);
let h_a = scene.add_shape(&hook_attach, RenderMode::Outline, offset_850);
let h_a_s = scene.add_shape(&hook_attach_stitch, RenderMode::DashedPerfect(vec![DASH_SIZE_ON, DASH_SIZE_OFF]), offset_850);
scene.add_again(h_a, offset_850_right);
scene.add_again(h_a_s, offset_850_right);
let mut pdf = PdfWriter::new("in", (1.0/100.0) * 72.0);
scene.render_all(&mut pdf);
pdf.write_out("collar.pdf");
}