This is nodfun.c in view mode; [Download] [Up]
#include "list.h" #include <stdio.h> #include <math.h> /* * wfun - write function file name with node list nod. * File written is text, with x and y pairs on each line. */ wfun(name, nod, cx, cy, cd, ysin) char *name; LIST *nod; int cx, cy; float cd; int ysin; { LIST *p; FILE *of, *fopen(); of = fopen(name, "w"); if (of == NULL) return(-1); for (p = nod; p; p = p->next) fprintf(of, "%6.3f\t%6.3f\n", cd * (p->x - cx), cd * (p->y - cy) * ysin); fclose(of); return(0); } /* * rfun - read function file name. if head != NULL, append the function * to the end of it. returns the head, which it creates if supplied one * is NULL. cx, cy and cd are used to set meter distances of the nodes * from the listener. Typical values would be cx = cy = 0, cd = 1.0. * cd is interpreted in meters. */ LIST *rfun(head, name, cx, cy, cd, ysin) LIST *head; char *name; float cx, cy, cd; int ysin; { LIST *p, *addnod(); FILE *i, *fopen(); float fx=0, fy=0; register int r; register float n = 0.0; i = fopen(name, "r"); if (i == NULL) return(NULL); for (p = head; p; p = p->next) n = p->n + 1.0; while ((r = fscanf(i, "%f%f", &fx, &fy)) != EOF && r == 2) { head = addnod(head, fy, fx, n, n, cx, cy, cd, ysin); n += 1.0; } fclose(i); return(head); } rmlist(nod) LIST *nod; { LIST *s, *o; for (s = nod; s; ) if (s->next != NULL) { s = s->next; free(s->last); } else { free(s); break; } } /* * linearly interpolate node between this and the next for x and y * where x,y are screen coordinates. */ LIST *ntrpnod(nod, cx, cy, cd) LIST *nod; int cx, cy; float cd; { LIST *newnod, *nxtnod, *t, *mknod(); if (nod == NULL) return(NULL); if (nod->next == NULL) return(NULL); else nxtnod = nod->next; newnod = mknod(); newnod->y = ((nxtnod->y - nod->y)/2) + nod->y; newnod->fy = -(newnod->y - cy) * cd; newnod->x = ((nxtnod->x - nod->x)/2) + nod->x; newnod->fx = (newnod->x - cx) * cd; newnod->time = ((nxtnod->time - nod->time)/2) + nod->time; newnod->n = nxtnod->n; for (t = nxtnod; t; t = t->next) t->n += 1.0; nod->next = newnod; newnod->last = nod; newnod->next = nxtnod; nxtnod->last = newnod; if (velocity(newnod)) return(NULL); return(newnod); } LIST *mknod() { return((LIST *) calloc(sizeof (LIST), 1)); } /*adrnod - returns node with same values of y and x.*/ LIST *adrnod(head, y, x) LIST *head; int x, y; { LIST *nod; for (nod = head; nod; nod = nod->next) if (nod->x == x && nod->y == y) return(nod); return(NULL); } /* putnod - position node to x,y coordinates where x,y are the integer * values of a screen location. 0,0 is the upper left hand corner. */ putnod(nod, y, x, cx, cy, cd) LIST *nod; int y, x, cx, cy; float cd; { if (nod == NULL) return(-1); nod->x = x; nod->fx = (x - cx) * cd; nod->y = y; nod->fy = -(y - cy) * cd; if (velocity(nod)) return(-1); return(0); } mvlist(head, cx, cy, cd, ysign) LIST *head; float cx, cy, cd; int ysign; { LIST *n; for (n = head; n; n = n->next) { n->y = cy + ysign * n->fy / cd; n->x = cx + n->fx / cd; } } scalist(head, xscl, yscl, cx, cy, cd, ysign) LIST *head; float xscl, yscl, cx, cy, cd; int ysign; { LIST *n; for (n = head; n; n = n->next) { n->fx *= xscl; n->fy *= yscl; n->y = cy + ysign * n->fy / cd; n->x = cx + n->fx / cd; if (velocity(n)) return(-1); } return(0); } offlist(head, xoff, yoff, cx, cy, cd, ysign) LIST *head; float xoff, yoff, cx, cy, cd; int ysign; { LIST *n; for (n = head; n; n = n->next) { n->fx += xoff; n->fy += yoff; n->y = cy + ysign * n->fy / cd; n->x = cx + n->fx / cd; } } float Pi; float getheta(x, y) float x, y; { register float theta; theta = atan2(y, x); if (theta < 0.0) theta = (Pi + theta) + Pi; return(theta); } float circlemod(x) float x; { register float twopi = 2.0 * Pi; while (x > twopi) x -= twopi; while (x < 0) x += twopi; return(x); } float getdistance(x, y) float x, y; { return(sqrt(x*x+y*y)); } rotlist(head, rot, cx, cy, cd, ysign) LIST *head; float rot, cx, cy, cd; int ysign; { LIST *n; float theta, D; Pi = 4.0 * atan(1.0); rot = 2.0 * Pi * rot / 360.0; for (n = head; n; n = n->next) { D = getdistance(n->fx, n->fy); theta = getheta(n->fx, n->fy); theta = circlemod(theta + rot); n->fx = D * cos(theta); n->fy = D * sin(theta); n->y = cy + ysign * n->fy / cd; n->x = cx + n->fx / cd; } } LIST *endnod; LIST *addnod(head, y, x, n, time, cx, cy, cd, ysign) LIST *head; float y, x, n, time, cx, cy, cd; int ysign; { LIST *newnod, *mknod(); if (head == NULL) newnod = endnod = head = mknod(); else newnod = mknod(); newnod->y = cy + ysign * y / cd; newnod->fy = y; newnod->x = cx + x / cd; newnod->fx = x; newnod->n = n; newnod->time = time; if (newnod != head) /* not starting new list */ { endnod->next = newnod; newnod->last = endnod; } if (velocity(newnod)) return(NULL); endnod = newnod; return(head); } /* * delnod - delete a node from the list. returns the previous node if * possible, else the next node. if the node is the only one, NULL is * returned. if the node to be deleted is the head of the linked list, * assign the next element to be head. Note that the ADDRESS of the * head of the linked list must be passed, not just its value. */ LIST *delnod(Hed, nod) LIST **Hed, *nod; { LIST *s, *r = NULL; if (nod == NULL) return(NULL); if (nod->last != NULL) nod->last->next = nod->next; else *Hed = nod->next; /* jump to new head */ if (nod->next != NULL) nod->next->last = nod->last; for (s = nod->next; s; s = s->next) s->n -= 1.0; if (velocity(nod->next)) return(NULL); if (nod->last != NULL) r = nod->last; else r = nod->next; free(nod); endnod = r; return(r); } velocity(nod) LIST *nod; { register float y, x, d, delta; if (nod == NULL) return; if (nod->last != NULL) { y = nod->fy - nod->last->fy; x = nod->fx - nod->last->fx; d = sqrt(y*y + x*x); if (d == 0.0) { nod->velocity = 0; return(0); } if ((delta = nod->time - nod->last->time) == 0.0) return(-1); nod->velocity = d / delta; } return(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.