Root/poly2d/p2d_gnuplot.c

1/*
2 * p2d_gnuplot.c - File I/O in gnuplot format
3 *
4 * Written 2012, 2015 by Werner Almesberger
5 * Copyright 2012, 2015 Werner Almesberger
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 */
12
13
14#include <stdbool.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <math.h>
18#include <errno.h>
19
20#include "poly2d.h"
21
22
23#define EPSILON 1e-6
24
25
26static void check_closed(struct p2d *p)
27{
28    if (!p)
29        return;
30    if (hypot(p->v->x-p->last->x, p->v->y-p->last->y) > EPSILON)
31        return;
32    free(p->last);
33    p->last = p->v;
34}
35
36
37struct p2d *p2d_read_gnuplot(FILE *file)
38{
39    struct p2d *res = NULL, **last = &res, *p = NULL;
40    char buf[1024];
41    double x, y;
42    int n;
43
44    while (fgets(buf, sizeof(buf), file)) {
45        if (*buf == '#')
46            continue;
47        n = sscanf(buf, "%lf %lf\n", &x, &y);
48        switch (n) {
49        case -1:
50            check_closed(p);
51            p = NULL;
52            break;
53        case 2:
54            break;
55        default:
56            errno = EINVAL;
57            return NULL;
58        }
59        if (!p) {
60            p = p2d_new();
61            *last = p;
62            last = &p->next;
63        }
64        p2d_append(p, v2d_new(x, y));
65    }
66    check_closed(p);
67    return res;
68}
69
70
71bool p2d_write_gnuplot(FILE *file, const struct p2d *p)
72{
73    const struct v2d *v;
74
75    v = p->v;
76    while (v) {
77        if (fprintf(file, "%g %g\n", v->x, v->y) < 0)
78            return 0;
79        v = v->next;
80        if (v == p->v) {
81            if (fprintf(file, "%g %g\n", v->x, v->y) < 0)
82                return 0;
83            break;
84        }
85    }
86    return fprintf(file, "\n") >= 0;
87}
88
89
90bool p2d_write_gnuplot_all(FILE *file, const struct p2d *p)
91{
92    while (p) {
93        if (!p2d_write_gnuplot(file, p))
94            return 0;
95        p = p->next;
96    }
97    return 1;
98}
99

Archive Download this file

Branches:
master



interactive