/* * shape.c - Toolpaths for basic shapes * * Written 2010-2011 by Werner Almesberger * Copyright 2010-2011 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include "path.h" #include "shape.h" static double arc2angle(double arc, double r) { return acos(1-arc*arc/(r*r)/2); } static void half_circle(struct path *path, double cx, double cy, double rx, double ry, double z, double s) { double m[4]; double x = rx, y = ry, tmp; double a; m[0] = cos(s); m[1] = -sin(s); m[2] = -m[1]; m[3] = m[0]; for (a = 0; a < M_PI; a += s) { path_add(path, cx+x, cy+y, z); tmp = x*m[0]+y*m[1]; y = x*m[2]+y*m[3]; x = tmp; } path_add(path, cx-rx, cy-ry, z); } struct path *slot(double xa, double ya, double xb, double yb, double z, double sr, double tr, double step, const char *id) { struct path *path; double dx = xb-xa; double dy = yb-ya; double s = arc2angle(step, sr); double nx, ny; double f; path = path_new(tr, id); if (sr <= tr) { path_add(path, xa, ya, z); path_add(path, xb, yb, z); } else { f = (sr-tr)/hypot(dx, dy); nx = -dy*f; ny = dx*f; half_circle(path, xa, ya, nx, ny, z, s); half_circle(path, xb, yb, -nx, -ny, z, s); path_add(path, xa+nx, ya+ny, z); } return path; } struct path *circle(double cx, double cy, double cz, double cr, double tr, double step, const char *id) { struct path *path; double s = arc2angle(step, cr); double a; path = path_new(tr, id); if (cr <= tr) { path_add(path, cx, cy, cz); } else { for (a = 0; a < 2*M_PI; a += s) path_add(path, cx+(cr-tr)*cos(a), cy+(cr-tr)*sin(a), cz); path_add(path, cx+(cr-tr), cy, cz); } return path; }