#include <stdio.h> #include <math.h> #include <time.h> #include <stdlib.h> #include "svg.h" // outside dimensions of hive - eventually these may be command-line parameters... float wood = 4.65; #define W 140 /* left-right */ //#define H 380 /* top-bottom */ #define H 190 /* top-bottom */ #define D 55 /* front-back */ int PREVIEW = 0; // -------------------------------------------------------- int mm(int m) { return m*100; } int in(int m) { return m*2540; } int ft(int m) { return in(m*12); } int mm_f(float m) { return (int)(m*100.0); } int in_f(float m) { return (int)(m*2540.0); } int ft_f(float m) { return in_f(m*12.0); } #define RED "#FF0000" #define GREEN "#00FF00" #define BLUE "#0000FF" #define PINK "#FFAAAA" #define WHITE "#FFFFFF" #define BLACK "#000000" #define BACKGROUND "#DDDDFF" #define ENGRAVE_TEXT BLACK #define COMMENT_TEXT BLUE #define HAIRLINE_f 0.003 #define VISIBLE_LINE_f 0.1 #define LIVE_FILL WHITE #define PREVIEW_FILL PINK static svg* psvg; #ifdef PREVIEW float linewidth_f = VISIBLE_LINE_f; char *fill = PREVIEW_FILL; #else float linewidth_f = HAIRLINE_f; char *fill = LIVE_FILL; #endif void hole_mm_f(float w, float h, float x, float y) { if (PREVIEW==0) { svg_rectangle(psvg, /* size */ mm_f(w), mm_f(h), /* at */ mm_f(x), mm_f(y), BACKGROUND, /* outline */ BACKGROUND, /* border-width */mm_f(linewidth_f), /* radius x,y */ 0,0); } else { svg_rectangle(psvg, /* size */ mm_f(w), mm_f(h), /* at */ mm_f(x), mm_f(y), WHITE, /* outline */ RED, /* border-width */mm_f(linewidth_f), /* radius x,y */ 0,0); } } void face(int w, int h, int x, int y) { svg_rectangle(psvg, /* size */ mm(w), mm(h), /* at */ mm(x), mm(y), fill, /* outline */ RED, /* border-width */mm_f(linewidth_f), /* radius x,y */ 0,0); } #ifdef NEVER svg_text(psvg, /* at */ mm(x+10), mm(y+25+1), "sans-serif", mm(3), /* fill colour */ COMMENT_TEXT, /* stroke colour */ COMMENT_TEXT, "5cm x 5cm square", ""); #endif void toothcomb(float x, float y, int steps, float spacing, int cut_depth) { int i; for (i = 0; i <= steps; i++) svg_line(psvg, RED, /* width */ mm_f(linewidth_f), /* from */ mm_f(x+i*spacing), mm_f(y), /* to */ mm_f(x+i*spacing), mm_f(y+cut_depth)); } void front_face(int x, int y) { float gap; int steps = (W-wood*2)/2; face(W, H, x+5, y+5); hole_mm_f(W-wood*2, 25, x+5+wood, y+5); hole_mm_f(W-wood*2-20, 100, x+5+wood+10, y+5+25+15); gap = W-wood*2 - steps*2.0; toothcomb(x+5+wood+gap/2, y+5+25, steps, 2, 3); // WARNING: NOT CENTERED } void back_face(int x, int y) { float gap; int steps = (W-wood*2)/2; face(W, H, x+5+W+5, y+5); hole_mm_f(W-wood*2, 25, x+5+W+5+wood, y+5); gap = W-wood*2 - steps*2.0; toothcomb(x+5+W+5+wood+gap/2, y+5+25, steps, 2, 3); // WARNING: NOT CENTERED } void left_face(int x, int y) { face(D, H, x+5+W+5+W+5, y+5); // sides hole_mm_f(wood, H, x+5+W+5+W+5, y+5); hole_mm_f(wood, H, x+5+W+5+W+5+D-wood, y+5); // top hole_mm_f(D, wood, x+5+W+5+W+5, y+5); hole_mm_f(D, wood, x+5+W+5+W+5, y+5+H-wood); } void right_face(int x, int y) { face(D, H, x+5+W+5+W+5+D+5, y+5); // sides hole_mm_f(wood, H, x+5+W+5+W+5+D+5, y+5); hole_mm_f(wood, H, x+5+W+5+W+5+D+5+D-wood, y+5); // top hole_mm_f(D, wood, x+5+W+5+W+5+D+5, y+5); hole_mm_f(D, wood, x+5+W+5+W+5+D+5, y+5+H-wood); } void top_face(int x, int y) { face(D, W, x+5+W+5+W+5+D+5+D+5, y+5); // sides hole_mm_f(wood, W, x+5+W+5+W+5+D+5+D+5, y+5); hole_mm_f(wood, W, x+5+W+5+W+5+D+5+D+5+D-wood, y+5); // top hole_mm_f(D, wood, x+5+W+5+W+5+D+5+D+5, y+5); hole_mm_f(D, wood, x+5+W+5+W+5+D+5+D+5, y+5+W-wood); } void shelf(int x, int y) { face(D, W, x+5+W+5+W+5+D+5+D+5, y+5+W+5); // sides hole_mm_f(wood, W, x+5+W+5+W+5+D+5+D+5, y+5+W+5); hole_mm_f(wood, W, x+5+W+5+W+5+D+5+D+5+D-wood, y+5+W+5); // top hole_mm_f(D, wood, x+5+W+5+W+5+D+5+D+5, y+5+W+5); hole_mm_f(D, wood, x+5+W+5+W+5+D+5+D+5, y+5+W-wood+W+5); } void ruler(int x, int y) { svg_line(psvg, RED, /* width */ mm_f(linewidth_f), /* from */ mm(x), mm(y), /* to */ mm(x+50), mm(y)); svg_line(psvg, RED, /* width */ mm_f(linewidth_f), /* from */ mm(x), mm(y), /* to */ mm(x), mm(y-5)); svg_line(psvg, RED, /* width */ mm_f(linewidth_f), /* from */ mm(x+50), mm(y), /* to */ mm(x+50), mm(y-5)); svg_text(psvg, /* at */ mm(x+10), mm(y-1), "sans-serif", mm(3), /* fill colour */ BLACK, /* stroke colour */ BLACK, "5cm line", ""); } void hive(int x, int y) { front_face(x,y); back_face(x,y); left_face(x,y); right_face(x,y); top_face(x,y); shelf(x,y); } int main(void) { PREVIEW = 0; linewidth_f = VISIBLE_LINE_f; fill = PREVIEW_FILL; psvg = svg_create(in(36), in(24)); // size of laser cutter bed if (psvg == NULL) { puts("psvg is NULL"); exit(EXIT_FAILURE); } else { svg_fill(psvg, BACKGROUND); } hive(20,20); svg_text(psvg, /* at */ mm(2), mm(4), "sans-serif", mm(3), /* fill colour */ COMMENT_TEXT, /* stroke colour */ COMMENT_TEXT, "THIS IS A PREVIEW-OPTIMISED VERSION. CUT THE OTHER FILE.", ""); svg_finalize(psvg); svg_save(psvg, "hive-preview.svg"); svg_free(psvg); PREVIEW = 1; linewidth_f = HAIRLINE_f; fill = LIVE_FILL; psvg = svg_create(in(36), in(24)); // size of laser cutter bed if (psvg == NULL) { puts("psvg is NULL"); exit(EXIT_FAILURE); } hive(20,20); svg_finalize(psvg); svg_save(psvg, "hive.svg"); svg_free(psvg); exit(EXIT_SUCCESS); return EXIT_FAILURE; }