Root/cameo/shape.c

1/*
2 * shape.c - Toolpaths for basic shapes
3 *
4 * Written 2010-2011 by Werner Almesberger
5 * Copyright 2010-2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <math.h>
15
16#include "path.h"
17#include "shape.h"
18
19
20static double arc2angle(double arc, double r)
21{
22    return acos(1-arc*arc/(r*r)/2);
23}
24
25
26static void half_circle(struct path *path,
27    double cx, double cy, double rx, double ry, double z, double s)
28{
29    double m[4];
30    double x = rx, y = ry, tmp;
31    double a;
32
33    m[0] = cos(s);
34    m[1] = -sin(s);
35    m[2] = -m[1];
36    m[3] = m[0];
37
38    for (a = 0; a < M_PI; a += s) {
39        path_add(path, cx+x, cy+y, z);
40        tmp = x*m[0]+y*m[1];
41        y = x*m[2]+y*m[3];
42        x = tmp;
43    }
44    path_add(path, cx-rx, cy-ry, z);
45}
46
47
48struct path *slot(double xa, double ya, double xb, double yb, double z,
49    double sr, double tr, double step, const char *id)
50{
51    struct path *path;
52    double dx = xb-xa;
53    double dy = yb-ya;
54    double s = arc2angle(step, sr);
55    double nx, ny;
56    double f;
57
58    path = path_new(tr, id);
59    if (sr <= tr) {
60        path_add(path, xa, ya, z);
61        path_add(path, xb, yb, z);
62    } else {
63        f = (sr-tr)/hypot(dx, dy);
64        nx = -dy*f;
65        ny = dx*f;
66
67        half_circle(path, xa, ya, nx, ny, z, s);
68        half_circle(path, xb, yb, -nx, -ny, z, s);
69        path_add(path, xa+nx, ya+ny, z);
70    }
71    return path;
72}
73
74
75struct path *circle(double cx, double cy, double cz, double cr, double tr,
76    double step, const char *id)
77{
78    struct path *path;
79    double s = arc2angle(step, cr);
80    double a;
81
82    path = path_new(tr, id);
83    if (cr <= tr) {
84        path_add(path, cx, cy, cz);
85    } else {
86        for (a = 0; a < 2*M_PI; a += s)
87            path_add(path,
88                cx+(cr-tr)*cos(a), cy+(cr-tr)*sin(a), cz);
89        path_add(path, cx+(cr-tr), cy, cz);
90    }
91    return path;
92}
93

Archive Download this file

Branches:
master



interactive