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
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <gki.h>
include <gset.h>
include "sgi.h"
define MAX_LTYPES 3 # max software line type patterns (excl. solid)
define MAX_LSEGMENTS 4 # max line segments per pattern
define LT_OFFSET 1 # offset to be subtracted from ltype code
# SGI_POLYLINE -- Draw a polyline. The polyline is defined by the array of
# points P, consisting of successive (x,y) coordinate pairs. The first point
# is not plotted but rather defines the start of the polyline. The remaining
# points define line segments to be drawn.
procedure sgi_polyline (p, npts)
short p[ARB] # points defining line
int npts # number of points, i.e., (x,y) pairs
pointer pl
int x, y
int len_p, i
include "sgi.com"
begin
if (npts < 2)
return
len_p = npts * 2
# Keep track of the number of drawing instructions since the last frame
# clear.
g_ndraw = g_ndraw + 1
# Update polyline attributes if necessary.
pl = SGI_PLAP(g_kt)
if (SGI_WIDTH(g_kt) != PL_WIDTH(pl)) {
call sgk_linewidth (g_out, nint (GKI_UNPACKREAL(PL_WIDTH(pl))))
SGI_WIDTH(g_kt) = PL_WIDTH(pl)
}
if (SGI_COLOR(g_kt) != PL_COLOR(pl)) {
call sgi_color (PL_COLOR(pl))
SGI_COLOR(g_kt) = PL_COLOR(pl)
}
if (PL_LTYPE(pl) == GL_CLEAR) {
# Ignore clear (erase) polylines.
;
} else if (PL_LTYPE(pl) != GL_SOLID) {
# Draw a dashed or dotted polyline of the indicated type.
call sgi_dashline (g_out, p, npts, PL_LTYPE(pl))
} else {
# Draw a solid polyline (usual case, optimized).
# Move to the first point.
x = p[1]
y = p[2]
call sgk_move (g_out, x, y)
# Draw the polyline.
for (i=3; i <= len_p; i=i+2) {
x = p[i]
y = p[i+1]
call sgk_draw (g_out, x, y)
}
}
end
# SGI_DASHLINE -- Draw a dashed or dotted polyline using the indicated line
# style.
procedure sgi_dashline (g_out, p, npts, ltype)
int g_out # output file
short p[ARB] # the polyline points
int npts # number of points, i.e., (x,y) pairs
int ltype # desired line type
bool penup
int len_p, i
real vlen, vpos, seglen, dx, dy
int oldx, oldy, newx, newy, penx, peny
int sgi_getseg()
begin
len_p = npts * 2
oldx = p[1]; oldy = p[2]
call sgk_move (g_out, oldx, oldy)
# Process each line segment in the polyline.
do i = 3, len_p, 2 {
newx = p[i]
newy = p[i+1]
# Compute VLEN, the length of the polyline line segment to be
# drawn, VPOS, the relative position along the line segment,
# and DX and DY, the scale factors to be applied to VPOS to get
# the x and y coordinates of a point along the line segment.
dx = newx - oldx
dy = newy - oldy
vlen = sqrt (dx*dx + dy*dy)
if (vlen < 1.0) # GKI units
next
dx = dx / vlen
dy = dy / vlen
vpos = 0.0
# For each line segment, get segments of the line type pattern
# until all of the current line segment has been drawn. The pattern
# wraps around indefinitely, following the polyline around the
# vertices with concern only for the total length traversed.
while (vlen - vpos >= 1.0) {
seglen = sgi_getseg (int (vlen - vpos), penup, ltype)
if (seglen < 1.0)
break
vpos = vpos + seglen
penx = oldx + vpos * dx
peny = oldy + vpos * dy
if (penup)
call sgk_move (g_out, penx, peny)
else
call sgk_draw (g_out, penx, peny)
}
oldx = newx
oldy = newy
}
end
# SGI_GETSEG -- Get a segment of a line style pattern. The segment extends
# from the current position in the pattern to either the next penup/pendown
# breakpoint in the pattern, or to the point MAXLEN units further along in
# the pattern. When the end of the pattern is reached wrap around and
# duplicate the pattern indefinitely.
int procedure sgi_getseg (maxlen, penup, ltype)
int maxlen # max length segment to be returned
bool penup # [out] pen up or pen down type segment?
int ltype # line type code
int seglen, seg, lt
int p_seg[MAX_LTYPES]
int p_nseg[MAX_LTYPES]
int p_segleft[MAX_LTYPES]
bool p_penup[MAX_LTYPES,MAX_LSEGMENTS]
int p_seglen[MAX_LTYPES,MAX_LSEGMENTS]
include "ltype.dat"
begin
lt = max (1, min (MAX_LTYPES, ltype - LT_OFFSET))
seg = p_seg[lt]
penup = p_penup[lt,seg]
repeat {
if (maxlen < p_segleft[lt]) {
seglen = maxlen
p_segleft[lt] = p_segleft[lt] - seglen
} else {
seglen = p_segleft[lt]
seg = seg + 1
if (seg > p_nseg[lt])
seg = 1
p_seg[lt] = seg
p_segleft[lt] = p_seglen[lt,seg]
}
} until (seglen > 0)
return (seglen)
end
|