#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;
}