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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <math.h>
include "ccp.h"
define DIAGSEP (g_plwsep / 0.8660254) # distance to vertex of hexagon
define PIOVER3 (PI / 3.0)
define PIOVER6 (PI / 6.0)
define SIN_MIN_HALFBISECTOR 0.1 # sine of minimum half-bisector
# CCP_DRAWSEG -- Draw a polyline segment, optionally simulating variable
# widths.
procedure ccp_drawseg (xseg, yseg, nsegpts, lwidth)
real xseg[ARB] # plotter coordinate array of contiguous points
real yseg[ARB]
int nsegpts # number of pts in array
int lwidth # line width relative to single width
int i, j
real pleft_x[MAXTRACES], pleft_y[MAXTRACES]
real pright_x[MAXTRACES], pright_y[MAXTRACES], lastp_x,lastp_y
real ahp2p1, theta, delx,dely, dx,dy, tx,ty
real rptheta4 ()
include "ccp.com"
data lastp_x/0.0/, lastp_y/0.0/
begin
if (nsegpts < 1)
return
if (lwidth > MAXTRACES) {
call eprintf ("WARNING: line width > MAXTRACES in ccp_drawseg\n")
call eprintf (" line width reset to %d\n")
call pargi (MAXTRACES)
lwidth = MAXTRACES
}
if (nsegpts == 1) { # 1 pt spcl bold
# Draw a single point as a hexagon lined up in the direction from
# the preceding point. Start bounding hexagon 60 degrees cc from
# projection of last point drawn (0,0 initially) through current pt.
# 'ahp2p1' = Angle from Horizontal at P1 to line P1 -> P2, etc.
ahp2p1 = rptheta4 (xseg[1], yseg[1], lastp_x, lastp_y)
lastp_x = xseg[1]
lastp_y = yseg[1]
theta = ahp2p1 - PIOVER6
# do even a single, interior point as a hexagon, up to lwidth times
do i = 1, lwidth {
tx = xseg[1] + (2 + i) * DIAGSEP * cos (theta)
ty = yseg[1] + (2 + i) * DIAGSEP * sin (theta)
call plot (tx, ty, CCP_UP)
# draw a bounding hexagon around point:
do j = 1, 6 {
theta = theta + PIOVER3
tx = xseg[1] + (2 + i) * DIAGSEP * cos (theta)
ty = yseg[1] + (2 + i) * DIAGSEP * sin (theta)
call plot (tx, ty, CCP_DOWN)
# Store maximum-x plotted for a "newframe" in ccp_clear.
g_max_x = max (tx, g_max_x)
}
# fill in a diagonal line across hexagon:
tx = xseg[1] + (2 + i) * DIAGSEP * cos (theta + PI)
ty = yseg[1] + (2 + i) * DIAGSEP * sin (theta + PI)
call plot (tx, ty, CCP_DOWN)
theta = theta + PIOVER3 # rotate spokes
}
} else { # nsegpts > 1
if (g_lwover || lwidth == PL_SINGLE) {
call plot (xseg[1], yseg[1], CCP_UP)
g_max_x = max (xseg[1], g_max_x)
do i = 2, nsegpts {
call plot (xseg[i], yseg[i], CCP_DOWN)
g_max_x = max (xseg[i], g_max_x)
}
} else if (lwidth > PL_SINGLE) {
# compute flanking points; by definition +-90 deg. from p1-p2,
# so first point is special case; do for all thicknesses:
call ccx_offsets (xseg[1]-xseg[2]+xseg[1],
yseg[1]-yseg[2]+yseg[1], xseg[1],yseg[1],
xseg[2],yseg[2], delx,dely)
do i = 1, lwidth - 1 {
pleft_x[i] = xseg[1] + i * delx
pleft_y[i] = yseg[1] + i * dely
pright_x[i] = xseg[1] - i * delx
pright_y[i] = yseg[1] - i * dely
}
# must draw each segment individually, to make flanks meet.
do i = 1, nsegpts - 2 {
# actual line segment in data:
call plot (xseg[i], yseg[i], CCP_UP)
call plot (xseg[i+1], yseg[i+1], CCP_DOWN)
g_max_x = max (xseg[i], g_max_x)
call ccx_offsets (xseg[i],yseg[i], xseg[i+1],yseg[i+1],
xseg[i+2],yseg[i+2], delx,dely)
# for each flanking line; p2 in middle, at temp origin
do j = 1, lwidth - 1 {
# point to left of p1-p2, facing p2:
dx = j * delx
dy = j * dely
tx = xseg[i+1] + dx
ty = yseg[i+1] + dy
call plot (pleft_x[j], pleft_y[j], CCP_UP)
call plot (tx, ty, CCP_DOWN)
pleft_x[j] = tx
pleft_y[j] = ty
# point to right of p1-p2, facing p2:
tx = xseg[i+1] - dx
ty = yseg[i+1] - dy
call plot (pright_x[j], pright_y[j], CCP_UP)
call plot (tx, ty, CCP_DOWN)
pright_x[j] = tx
pright_y[j] = ty
}
}
# last point:
call plot (xseg[nsegpts-1], yseg[nsegpts-1], CCP_UP)
call plot (xseg[nsegpts], yseg[nsegpts], CCP_DOWN)
g_max_x = max (xseg[nsegpts-1], g_max_x)
g_max_x = max (xseg[nsegpts], g_max_x)
# save this point for a possible following dotted line segment:
lastp_x = xseg[nsegpts]
lastp_y = yseg[nsegpts]
# square the flanking lines:
call ccx_offsets (xseg[nsegpts-1], yseg[nsegpts-1],
xseg[nsegpts], yseg[nsegpts],
xseg[nsegpts] * 2.0 - xseg[nsegpts-1],
yseg[nsegpts] * 2.0 - yseg[nsegpts-1],
delx, dely)
do i = 1, lwidth - 1 {
tx = xseg[nsegpts] + i * delx
ty = yseg[nsegpts] + i * dely
call plot (pleft_x[i], pleft_y[i], CCP_UP)
call plot (tx, ty, CCP_DOWN)
tx = xseg[nsegpts] - i * delx
ty = yseg[nsegpts] - i * dely
call plot (pright_x[i], pright_y[i], CCP_UP)
call plot (tx, ty, CCP_DOWN)
}
}
}
end
# CCX_OFFSETS -- return offsets in x, y from point 2 to one level of line width
# simulation, given points 1, 2, 3.
procedure ccx_offsets (p1x,p1y, p2x,p2y, p3x,p3y, delx,dely)
real p1x,p1y # input: point 1 is previous point
real p2x,p2y # input: point 2 is current point (middle of the three)
real p3x,p3y # input: point 3 is succeeding point
real delx,dely # output: offsets from point 2 to one flanking point
real ahp2p1 # Angle from Horizontal to line p2-->p1, etc.
real ahp2p3, ap1p2p3, ahbisector, sintheta, r
real rptheta4 ()
include "ccp.com"
begin
# convention is that p2 is current point, at temporary origin; p1
# is "behind", and p3 is "ahead" of the current point, p2.
# "ahp2p1" = angle from horizontal to segment p2->p1
# "ap1p2p3" = angle from p1 to p2 to p3
# "ahbisector" = angle from horizontal (+x) to bisector of p1->p2->p3
ahp2p1 = rptheta4 (p2x,p2y, p1x,p1y)
ahp2p3 = rptheta4 (p2x,p2y, p3x,p3y)
ap1p2p3 = ahp2p1 - ahp2p3
ahbisector = ahp2p3 + 0.5 * ap1p2p3
sintheta = sin (ahp2p1 - ahbisector)
# very small angles cause extremely exaggerated vertices; truncate
# at arbitrary multiple of plwsep; 10*plwsep is eqv. to 11.5 deg. bisect
if (abs (sintheta) < SIN_MIN_HALFBISECTOR) {
r = g_plwsep / SIN_MIN_HALFBISECTOR
if (sintheta < 0.0)
r = -r
} else
r = g_plwsep / sintheta
delx = r * cos (ahbisector)
dely = r * sin (ahbisector)
end
|