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