Root/gnuplot.c

1/*
2 * gnuplot.c - Dump objects in gnuplot 2D format
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 by 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 <stdio.h>
15#include <string.h>
16
17#include "coord.h"
18#include "inst.h"
19#include "gnuplot.h"
20
21
22#define ARC_STEP 0.1 /* @@@ make configurable */
23
24
25static void recurse_id(FILE *file, const struct inst *inst)
26{
27    if (inst->obj->frame->name) {
28        recurse_id(file, inst->outer);
29        fprintf(file, "/%s", inst->obj->frame->name);
30    }
31}
32
33
34static void identify(FILE *file, const struct inst *inst)
35{
36    fprintf(file, "#%%id=");
37    recurse_id(file, inst);
38    fprintf(file, "\n");
39}
40
41
42static void gnuplot_line(FILE *file, const struct inst *inst)
43{
44    double xa, ya, xb, yb;
45
46    xa = units_to_mm(inst->base.x);
47    ya = units_to_mm(inst->base.y);
48    xb = units_to_mm(inst->u.rect.end.x);
49    yb = units_to_mm(inst->u.rect.end.y);
50
51    identify(file, inst);
52    fprintf(file, "#%%r=%f\n%f %f\n%f %f\n\n",
53        units_to_mm(inst->u.rect.width), xa, ya, xb, yb);
54}
55
56
57static void gnuplot_rect(FILE *file, const struct inst *inst)
58{
59    double xa, ya, xb, yb;
60
61    xa = units_to_mm(inst->base.x);
62    ya = units_to_mm(inst->base.y);
63    xb = units_to_mm(inst->u.rect.end.x);
64    yb = units_to_mm(inst->u.rect.end.y);
65
66    identify(file, inst);
67    fprintf(file, "#%%r=%f\n", units_to_mm(inst->u.rect.width));
68    fprintf(file, "%f %f\n", xa, ya);
69    fprintf(file, "%f %f\n", xa, yb);
70    fprintf(file, "%f %f\n", xb, yb);
71    fprintf(file, "%f %f\n", xb, ya);
72    fprintf(file, "%f %f\n\n", xa, ya);
73}
74
75
76static void gnuplot_circ(FILE *file, const struct inst *inst)
77{
78    double cx, cy, r;
79    double a;
80    int n, i;
81
82    cx = units_to_mm(inst->base.x);
83    cy = units_to_mm(inst->base.y);
84    r = units_to_mm(inst->u.arc.r);
85
86    identify(file, inst);
87    fprintf(file, "#%%r=%f\n", units_to_mm(inst->u.arc.width));
88
89    n = ceil(2*r*M_PI/ARC_STEP);
90    if (n < 2)
91        n = 2;
92
93    for (i = 0; i <= n; i++) {
94        a = 2*M_PI/n*i;
95        fprintf(file, "%f %f\n", cx+r*sin(a), cy+r*cos(a));
96    }
97    fprintf(file, "\n");
98}
99
100
101static void gnuplot_arc(FILE *file, const struct inst *inst)
102{
103    double cx, cy, r;
104    double a, tmp;
105    int n, i;
106
107    cx = units_to_mm(inst->base.x);
108    cy = units_to_mm(inst->base.y);
109    r = units_to_mm(inst->u.arc.r);
110
111    a = inst->u.arc.a2-inst->u.arc.a1;
112    while (a <= 0)
113        a += 360;
114    while (a > 360)
115        a =- 360;
116
117    n = ceil(2*r*M_PI/360*a/ARC_STEP);
118    if (n < 2)
119        n = 2;
120
121    for (i = 0; i <= n; i++) {
122        tmp = (inst->u.arc.a1+a/n*i)*M_PI/180;
123        fprintf(file, "%f %f\n", cx+r*cos(tmp), cy+r*sin(tmp));
124    }
125
126    fprintf(file, "\n");
127}
128
129
130static void gnuplot_inst(FILE *file, enum inst_prio prio,
131    const struct inst *inst)
132{
133    switch (prio) {
134    case ip_pad_copper:
135    case ip_pad_special:
136        /* complain ? */
137        break;
138    case ip_hole:
139        /* complain ? */
140        break;
141    case ip_line:
142        gnuplot_line(file, inst);
143        break;
144    case ip_rect:
145        gnuplot_rect(file, inst);
146        break;
147    case ip_circ:
148        gnuplot_circ(file, inst);
149        break;
150    case ip_arc:
151        gnuplot_arc(file, inst);
152        break;
153    default:
154        /*
155         * Don't try to export vectors, frame references, or
156         * measurements.
157         */
158        break;
159    }
160}
161
162
163static void gnuplot_package(FILE *file, const struct pkg *pkg)
164{
165    enum inst_prio prio;
166    const struct inst *inst;
167
168    /*
169     * Package name
170     */
171    fprintf(file, "# %s\n", pkg->name);
172
173    FOR_INST_PRIOS_UP(prio) {
174        for (inst = pkgs->insts[prio]; inst; inst = inst->next)
175            gnuplot_inst(file, prio, inst);
176        for (inst = pkg->insts[prio]; inst; inst = inst->next)
177            gnuplot_inst(file, prio, inst);
178    }
179
180    fprintf(file, "\n");
181}
182
183
184int gnuplot(FILE *file, const char *one)
185{
186    const struct pkg *pkg;
187
188    for (pkg = pkgs; pkg; pkg = pkg->next)
189        if (pkg->name)
190            if (!one || !strcmp(pkg->name, one))
191                gnuplot_package(file, pkg);
192
193    fflush(file);
194    return !ferror(file);
195}
196

Archive Download this file

Branches:
master



interactive