File: g_vector.c

package info (click to toggle)
plotutils 2.0-2
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 5,964 kB
  • ctags: 2,522
  • sloc: ansic: 38,416; sh: 1,853; yacc: 856; makefile: 181; lex: 144
file content (90 lines) | stat: -rw-r--r-- 1,938 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* This file includes vector-related utility routines. */

#include "sys-defines.h"
#include "plot.h"
#include "extern.h"

#define VLENGTH(v) sqrt( (v).x * (v).x + (v).y * (v).y )

/* scales an input vector to a new length and returns it */
Vector *
#ifdef _HAVE_PROTOS
_vscale(Vector *v, double newlen) 
#else
_vscale(v, newlen) 
     Vector *v;
     double newlen;
#endif
{
  double len = VLENGTH(*v);
  
  if (len != 0.0) 
    { 
      v->x *= newlen/len;   
      v->y *= newlen/len; 
    }
  return(v);
}

/* compute angle (arctangent) of 2-D vector via atan2, but standardize
   handling of singular cases */
double
#ifdef _HAVE_PROTOS
_xatan2 (double y, double x)
#else
_xatan2 (y, x)
     double y, x;
#endif
{
  if (y == 0.0 && x >= 0.0)
    return 0.0;
  else if (y == 0.0 && x < 0.0)
    return M_PI;
  else if (x == 0.0 && y >= 0.0)
    return M_PI_2;
  else if (x == 0.0 && y < 0.0)
    return -(M_PI_2);
  else
    return atan2(y, x);
}

/* _fixcenter adjusts the location of the point pc so that it can be used
   as the center of a circle or circular arc through p0 and p1.  If pc does
   not lie on the line that perpendicularly bisects the line segment from
   p0 to p1, it is projected orthogonally onto it.  p0 and p1 are assumed
   not to be coincident. */
Point
#ifdef _HAVE_PROTOS
_truecenter(Point p0, Point p1, Point pc)
#else
_truecenter(p0, p1, pc)
     Point p0, p1, pc;
#endif
{
  Point pm;
  Vector a, b, c;
  double scale;
  
  /* midpoint */
  pm.x = 0.5 * (p0.x + p1.x);
  pm.y = 0.5 * (p0.y + p1.y);  

  /* a points along perpendicular bisector */
  a.x = -p1.y + p0.y; 
  a.y =  p1.x - p0.x;

  /* b points from midpoint to pc */
  b.x = pc.x - pm.x;
  b.y = pc.y - pm.y;

  /* c is orthogonal projection of b onto a */
  scale = (a.x * b.x + a.y * b.y) / (a.x * a.x + a.y * a.y);
  c.x = scale * a.x;
  c.y = scale * a.y;

  /* adjust pc */
  pc.x = pm.x + c.x;
  pc.y = pm.y + c.y;

  return pc;
}