#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
//
// This generates a jig that can be attached to the Dremel drill press, to
// help route a hole in a Vectrex cartridge suitable for a ZIF socket by
// manually sliding the cartridge lid around within the captive enclosure.
//
#include "gpc.h"
#include "svg.h"
// Corel-svg uses floating point units in millimeters. This code uses 1/100ths of a mm,
// (i.e. 10 microns per unit), stored in integers. May later re-engineer as micron base units.
#define mm(m) (int)roundf((m)*100.0)
#define in(m) (int)roundf((m)*2540.0)
#define ft(m) in((m)*12.0)
#define PLATFORM_HEIGHT mm(144.2)
#define PLATFORM_WIDTH mm(152.6)
#define WOOD_THICKNESS mm(4.65) // only used when creating joints
#define LASER_KERF mm(0.57) // really tight fit, but comes loose after a few removals and reinsertions
#define HALF_LASER_KERF (LASER_KERF/2)
#define ROUTER_KERF mm(2.8) /* check with micrometer */
#define HALF_ROUTER_KERF (ROUTER_KERF/2)
#define SAFETY mm(0) // make the initial test holes 4mm in on all sides, then reduce 'safety' to 0 if all centered OK. Test with hand-made cart.
//#define SAFETY mm(4) // make the initial test holes 4mm in on all sides, then reduce 'safety' to 0 if all centered OK. Test with hand-made cart.
#define CART_WIDTH mm(71.5)
#define CART_HEIGHT mm(74.3)
#define ZIF_WIDTH (mm(22.9)-SAFETY*2-ROUTER_KERF)
#define ZIF_HEIGHT (mm(50.4)-SAFETY*2-ROUTER_KERF)
#define HOLE_WIDTH (CART_WIDTH+ZIF_WIDTH) // to do: subtract router width from both.
#define HOLE_HEIGHT (CART_HEIGHT+ZIF_HEIGHT)
// center of hole vs center of cartridge,
// determined by inspection, so takes into account
// that the drill bit is not in the true center of the base:
#define POSITION_X_OFFSET mm(4.5) // x is 0 at left increasing to the right (was 3.9)
#define POSITION_Y_OFFSET mm(-7.5) // y is 0 at top increasing downwards
// --------------------------------------------------------
#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 mm(0.01) // for cutting
#define VISIBLE_LINE mm(0.2) // for preview
//#define MARGIN mm(0)
#define MARGIN mm(5.0)
#define LIVE_FILL WHITE
#define PREVIEW_FILL PINK
static svg* psvg;
int PREVIEW;
// value of these depends on PREVIEW
int linewidth;
char *fill;
int stage_width = mm(0.0), stage_height = mm(0.0);
void hole(int w, int h, int x, int y) {
if (x+w > stage_width) stage_width = x+w+MARGIN; // not 'MARGIN*2' because MARGIN already added explicitly by user.
if (y+h > stage_height) stage_height = y+h+MARGIN;
if (PREVIEW) {
svg_rectangle(psvg, /* size */ w, h, /* at */ x, y,
BACKGROUND, /* outline */ BACKGROUND, /* border-width */linewidth,
/* radius x,y */ 0,0);
} else {
svg_rectangle(psvg, /* size */ w, h, /* at */ x, y,
WHITE, /* outline */ RED, /* border-width */linewidth,
/* radius x,y */ 0,0);
}
}
void face(int w, int h, int x, int y) {
if (x+w > stage_width) stage_width = x+w+MARGIN;
if (y+h > stage_height) stage_height = y+h+MARGIN;
svg_rectangle(psvg, /* size */ w, h, /* at */ x, y,
fill, /* outline */ RED, /* border-width */linewidth,
/* radius x,y */ mm(0),mm(0));
}
void cross_ruler(int x, int y) {
svg_line(psvg, RED, /* width */ linewidth, /* from */ x-mm(25), y, /* to */ x+mm(25), y);
svg_line(psvg, RED, /* width */ linewidth, /* from */ x-mm(25), y-mm(2.5), /* to */ x-mm(25), y+mm(2.5));
svg_line(psvg, RED, /* width */ linewidth, /* from */ x+mm(25), y-mm(2.5), /* to */ x+mm(25), y+mm(2.5));
svg_text(psvg, /* at */ x+mm(10), y-mm(3),
"sans-serif",
mm(3),
/* fill colour */ (PREVIEW ? COMMENT_TEXT : ENGRAVE_TEXT), /* stroke colour */ (PREVIEW ? COMMENT_TEXT : ENGRAVE_TEXT), "5cm line", "");
svg_line(psvg, RED, /* width */ linewidth, /* from */ x, y-in(1), /* to */ x, y+in(1));
svg_line(psvg, RED, /* width */ linewidth, /* from */ x-mm(2.5), y-in(1), /* to */ x+mm(2.5), y-in(1));
svg_line(psvg, RED, /* width */ linewidth, /* from */ x-mm(2.5), y+in(1), /* to */ x+mm(2.5), y+in(1));
svg_text(psvg, /* at */ x-mm(5), y+mm(5)+in(1),
"sans-serif",
mm(3),
/* fill colour */ (PREVIEW ? COMMENT_TEXT : ENGRAVE_TEXT), /* stroke colour */ (PREVIEW ? COMMENT_TEXT : ENGRAVE_TEXT), "2in line", "");
}
void do_face(void) {
face(PLATFORM_WIDTH, PLATFORM_HEIGHT, MARGIN,MARGIN); // outer 4in x 4in box
}
void do_hole(void) {
hole(HOLE_WIDTH, HOLE_HEIGHT, MARGIN + (PLATFORM_WIDTH-HOLE_WIDTH)/2+POSITION_Y_OFFSET,
MARGIN + (PLATFORM_HEIGHT-HOLE_HEIGHT)/2+POSITION_X_OFFSET
); // inner hole for cartridge
//hole(HOLE_HEIGHT, HOLE_WIDTH, MARGIN + (PLATFORM_HEIGHT-HOLE_HEIGHT)/2+POSITION_X_OFFSET,
// MARGIN + (PLATFORM_WIDTH-HOLE_WIDTH)/2+POSITION_Y_OFFSET); // inner hole for cartridge
}
int main(void) {
// stage_width = in(36.0)-MARGIN*2; stage_height = in(24.0)-MARGIN*2;
for (PREVIEW = 1; PREVIEW >= -1; PREVIEW--) { // do preview first to get size
linewidth = PREVIEW ? VISIBLE_LINE : HAIRLINE;
fill = PREVIEW ? PREVIEW_FILL : LIVE_FILL;
psvg = svg_create(stage_width, stage_height); // size of laser cutter bed - either fixed, or 5mm margin around drawing below
stage_width = mm(0.0); stage_height = mm(0.0);
if (psvg == NULL) {
puts("psvg is NULL");
exit(EXIT_FAILURE);
} else {
if (PREVIEW) svg_fill(psvg, BACKGROUND);
}
if (PREVIEW) {
do_face();
do_hole();
}
if (PREVIEW) svg_text(psvg,
/* at */ MARGIN+mm(2.0), mm(3.5),
"sans-serif", mm(3.0),
/* fill colour */ COMMENT_TEXT, /* stroke colour */ COMMENT_TEXT,
"THIS IS A PREVIEW-OPTIMISED VERSION. CUT THE OTHER FILE.", "");
if (PREVIEW) svg_text(psvg,
/* at */ MARGIN+mm(2.0), mm(3.5)+PLATFORM_HEIGHT+mm(5),
"sans-serif", mm(3.0),
/* fill colour */ COMMENT_TEXT, /* stroke colour */ COMMENT_TEXT,
"USING 4mm SAFETY MARGIN! SET TO 0 FOR LIVE CUT!", "");
svg_text(psvg,
/* at */ mm(70), mm(-13) /* left/right as seen on screen More neg pushes text to right. */,
"sans-serif", mm(6.0),
/* fill colour */ (PREVIEW ? COMMENT_TEXT : ENGRAVE_TEXT), /* stroke colour */ (PREVIEW ? COMMENT_TEXT : ENGRAVE_TEXT),
"FRONT", " transform=\"rotate(90)\"");
cross_ruler(MARGIN+PLATFORM_WIDTH/2-mm(4), MARGIN+PLATFORM_HEIGHT/2-mm(1.5));
// more neg moves cross up as viewed on screen
// more neg moves cross left as viewed on screem
if (!PREVIEW) {
do_hole();
do_face();
}
svg_finalize(psvg);
svg_save(psvg, PREVIEW ? "zifjig-preview.svg" : "zifjig.svg");
svg_free(psvg);
}
exit(EXIT_SUCCESS);
return EXIT_FAILURE;
}