cae-tools/poly2d/p2d_gnuplot.c

99 lines
1.7 KiB
C

/*
* p2d_gnuplot.c - File I/O in gnuplot format
*
* Written 2012, 2015 by Werner Almesberger
* Copyright 2012, 2015 Werner Almesberger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include "poly2d.h"
#define EPSILON 1e-6
static void check_closed(struct p2d *p)
{
if (!p)
return;
if (hypot(p->v->x-p->last->x, p->v->y-p->last->y) > EPSILON)
return;
free(p->last);
p->last = p->v;
}
struct p2d *p2d_read_gnuplot(FILE *file)
{
struct p2d *res = NULL, **last = &res, *p = NULL;
char buf[1024];
double x, y;
int n;
while (fgets(buf, sizeof(buf), file)) {
if (*buf == '#')
continue;
n = sscanf(buf, "%lf %lf\n", &x, &y);
switch (n) {
case -1:
check_closed(p);
p = NULL;
break;
case 2:
break;
default:
errno = EINVAL;
return NULL;
}
if (!p) {
p = p2d_new();
*last = p;
last = &p->next;
}
p2d_append(p, v2d_new(x, y));
}
check_closed(p);
return res;
}
bool p2d_write_gnuplot(FILE *file, const struct p2d *p)
{
const struct v2d *v;
v = p->v;
while (v) {
if (fprintf(file, "%g %g\n", v->x, v->y) < 0)
return 0;
v = v->next;
if (v == p->v) {
if (fprintf(file, "%g %g\n", v->x, v->y) < 0)
return 0;
break;
}
}
return fprintf(file, "\n") >= 0;
}
bool p2d_write_gnuplot_all(FILE *file, const struct p2d *p)
{
while (p) {
if (!p2d_write_gnuplot(file, p))
return 0;
p = p->next;
}
return 1;
}