aboutsummaryrefslogtreecommitdiff
path: root/sys/gio/cursor/gtrwsclip.x
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /sys/gio/cursor/gtrwsclip.x
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'sys/gio/cursor/gtrwsclip.x')
-rw-r--r--sys/gio/cursor/gtrwsclip.x144
1 files changed, 144 insertions, 0 deletions
diff --git a/sys/gio/cursor/gtrwsclip.x b/sys/gio/cursor/gtrwsclip.x
new file mode 100644
index 00000000..3a0a384b
--- /dev/null
+++ b/sys/gio/cursor/gtrwsclip.x
@@ -0,0 +1,144 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+# GTR_POLYCLIP -- Clip a convex polygon to a box. If the polygon is entirely
+# outside the box 0 is returned; if the polygon is entirely within the box 1
+# is returned, otherwise the polygon is clipped and a value other than 0 or 1
+# is returned. This is based on code by Paul Heckbert from Graphics Gems,
+# 1985/1989.
+
+int procedure gtr_polyclip (pv, npts, x1, x2, y1, y2)
+
+short pv[ARB] #U polygon to be clipped
+int npts #U number of points in polygon
+int x1,x2,y1,y2 #I clipping box
+
+pointer sp, p1, p2, pt
+int x1out, x2out, y1out, y2out, i
+int gtr_cliptoplane()
+define nopts_ 91
+
+begin
+ x1out = 0; x2out = 0
+ y1out = 0; y2out = 0
+
+ # Count vertices which are outside with respect to each of the
+ # four planes.
+
+ do i = 1, npts*2, 2 {
+ if (pv[i+0] < x1) x1out = x1out + 1
+ if (pv[i+0] > x2) x2out = x2out + 1
+ if (pv[i+1] < y1) y1out = y1out + 1
+ if (pv[i+1] > y2) y2out = y2out + 1
+ }
+
+ # Is the polygon entirely inside the clipping box?
+ if (x1out + x2out + y1out + y2out == 0)
+ return (1)
+
+ # Is the polygon entirely outside the clipping box?
+ if (x1out == npts || x2out == npts || y1out == npts || y2out == npts)
+ return (0)
+
+ # If we get here the polygon partially intersects the clipping box.
+ # Clip against each of the planes that might cut the polygon, clipping
+ # the previously clipped polygon in each step. This is done in
+ # floating point to minimize accumulation of error when interpolating
+ # to the clipping plane to compute a new polygon vertex when the plane
+ # is crossed.
+
+ call smark (sp)
+ call salloc (p1, npts * 4, TY_REAL)
+ p2 = p1 + npts * 2
+
+ call achtsr (pv, Memr[p1], npts * 2)
+
+ if (x1out > 0)
+ if (gtr_cliptoplane (p1, p2, npts, 0, -1.0, real(x1)) == 0)
+ goto nopts_
+ else {
+ pt = p1; p1 = p2; p2 = pt
+ }
+ if (x2out > 0)
+ if (gtr_cliptoplane (p1, p2, npts, 0, 1.0, real(x2)) == 0)
+ goto nopts_
+ else {
+ pt = p1; p1 = p2; p2 = pt
+ }
+ if (y1out > 0)
+ if (gtr_cliptoplane (p1, p2, npts, 1, -1.0, real(y1)) == 0)
+ goto nopts_
+ else {
+ pt = p1; p1 = p2; p2 = pt
+ }
+ if (y2out > 0)
+ if (gtr_cliptoplane (p1, p2, npts, 1, 1.0, real(y2)) == 0)
+ goto nopts_
+ else {
+ pt = p1; p1 = p2; p2 = pt
+ }
+
+ call achtrs (Memr[p1], pv, npts * 2)
+ call sfree (sp)
+ return (npts)
+
+nopts_
+ call sfree (sp)
+ return (0)
+end
+
+
+# GTR_CLIPTOPLANE -- Clip the convex polygon P1 against a plane, copying
+# the inbounds portion to the output polygon P2.
+
+int procedure gtr_cliptoplane (p1, p2, npts, index, s, ref)
+
+pointer p1 #I pointer to input polygon
+pointer p2 #I pointer to output polygon
+int npts #U number of polygon points or vertices
+int index #I index of coordinate to be tested
+real s #I sign for comparison
+real ref #I value to compare against
+
+int nout, i
+pointer op, u, v
+real tu, tv, t
+
+begin
+ nout = 0
+ op = p2
+
+ u = p1 + (npts - 1) * 2
+ tu = s * Memr[u+index] - ref
+ v = p1
+
+ do i = 1, npts {
+ # On old polygon P1, U is previous vertex, V is current vertex,
+ # TV is negative if vertex V is in.
+
+ tv = s * Memr[v+index] - ref
+
+ if (! ((tu <= 0 && tv <= 0) || (tu > 0 && tv > 0))) {
+ # Edge crosses plane; add intersection point to P2.
+ t = tu / (tu - tv)
+ Memr[op+0] = Memr[u+0] + t * (Memr[v+0] - Memr[u+0])
+ Memr[op+1] = Memr[u+1] + t * (Memr[v+1] - Memr[u+1])
+ nout = nout + 1
+ op = op + 2
+ }
+
+ if (tv <= 0) {
+ # Vertex V is in, copy it out.
+ Memr[op+0] = Memr[v+0]
+ Memr[op+1] = Memr[v+1]
+ nout = nout + 1
+ op = op + 2
+ }
+
+ u = v
+ tu = tv
+ v = v + 2
+ }
+
+ npts = nout
+ return (nout)
+end