aboutsummaryrefslogtreecommitdiff
path: root/sys/gio/glabax/glbfind.x
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /sys/gio/glabax/glbfind.x
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'sys/gio/glabax/glbfind.x')
-rw-r--r--sys/gio/glabax/glbfind.x339
1 files changed, 339 insertions, 0 deletions
diff --git a/sys/gio/glabax/glbfind.x b/sys/gio/glabax/glbfind.x
new file mode 100644
index 00000000..b9ff3975
--- /dev/null
+++ b/sys/gio/glabax/glbfind.x
@@ -0,0 +1,339 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <mach.h>
+include <gio.h>
+include "glabax.h"
+
+# GLB_FIND_TICKS -- Find the optimal positions for the tick marks on an axis.
+# If rounding is enabled, extend the WCS out to the next tick outside the
+# boundary on either end of the axis. Since this routine may modify the WCS
+# it must be called before any other routines (e.g., glb_setaxes). Our task
+# is to position the major ticks in world coordinates at round numbers, e.g.,
+# 10, 20, 30 for a linear scale or 10, 100, 1000 for a log scale. The minor
+# ticks are evenly distributed over the range between the major ticks. If
+# log scaling is in use the step size between ticks will change by an order
+# of magnitude (by the factor KSTEP) in each decade of the log scale, i.e.,
+# at each major tick. All tick positions and offsets are output in world
+# coordinates.
+
+procedure glb_find_ticks (gp, ap, ax1, ax2, angle)
+
+pointer gp # graphics descriptor
+pointer ap # axis parameters (from graphics descriptor)
+pointer ax1, ax2 # axis descriptors (output)
+int angle # axis orientation, 0 or 90 degrees
+
+pointer w
+int logflag, nminor, scaling, t1, t2
+real char_height, char_width, wctick, tval
+real p1, p2, tp1, tp2, wcp1, tick1, step, minor_step, length
+
+bool fp_equalr()
+int gt_ndigits()
+real ggetr(), elogr(), aelogr(), glb_minorstep()
+
+begin
+ w = GP_WCSPTR (gp, GP_WCS(gp))
+
+ # Start by zeroing the AX structures so that we do not have to zero
+ # fields explicitly. This is a bit tricky because we are implicitly
+ # setting fields that are not named, but it saves time and space.
+
+ call aclri (Memi[ax1], LEN_AX)
+ call aclri (Memi[ax2], LEN_AX)
+
+ # If ticks are not to be drawn or if there are fewer than 2 ticks then
+ # we are done.
+
+ if (GL_NMAJOR(ap) <= 2)
+ return
+
+ # Call the tick placement algorithm to determine where to put the major
+ # tick marks. The output of this block are the variables P1 and P1,
+ # the world coords of the ends of the axis, and TICK1 and STEP, the
+ # world coords of the first tick and separation in world coords between
+ # major ticks.
+
+ if (angle == 0) {
+ p1 = WCS_WX1(w)
+ p2 = WCS_WX2(w)
+ scaling = WCS_XTRAN(w)
+ } else {
+ p1 = WCS_WY1(w)
+ p2 = WCS_WY2(w)
+ scaling = WCS_YTRAN(w)
+ }
+
+ AX_SCALING(ax1) = scaling
+ AX_SCALING(ax2) = scaling
+
+ if (scaling == LOG) {
+ p1 = log10 (p1)
+ p2 = log10 (p2)
+ logflag = YES
+ } else if (scaling == ELOG) {
+ p1 = elogr (p1)
+ p2 = elogr (p2)
+ logflag = YES
+ } else
+ logflag = NO
+
+ # Call the tick placement algorithm.
+ call gtickr (p1, p2, GL_NMAJOR(ap), logflag, tick1, step)
+
+ # If rounding is enabled, extend the WCS out to the next major tick
+ # position outward on either end. Always round if log scaling.
+
+ if (GL_ROUND(ap) == YES || scaling != LINEAR) {
+ if (!fp_equalr (p1, tick1)) {
+ tick1 = tick1 - step
+ p1 = tick1
+ }
+
+ length = (p2 - p1) / step
+ if (!fp_equalr (p1 + int(length) * step, p2))
+ p2 = p1 + (int(length) + 1) * step
+
+ if (scaling == ELOG) {
+ tp1 = aelogr (p1)
+ tp2 = aelogr (p2)
+ } else if (scaling == LOG) {
+ tp1 = 10.0 ** p1
+ tp2 = 10.0 ** p2
+ } else {
+ tp1 = p1
+ tp2 = p2
+ }
+
+ if (angle == 0) {
+ WCS_WX1(w) = tp1
+ WCS_WX2(w) = tp2
+ } else {
+ WCS_WY1(w) = tp1
+ WCS_WY2(w) = tp2
+ }
+
+ GP_WCSSTATE(gp) = MODIFIED
+ }
+
+ # Compute the coords of the axis endpoint and of the first tick in world
+ # coords.
+
+ if (scaling == LINEAR) {
+ wctick = tick1
+ wcp1 = p1
+ } else if (scaling == LOG) {
+ wctick = 10.0 ** tick1
+ wcp1 = 10.0 ** p1
+ } else {
+ wctick = aelogr (tick1)
+ wcp1 = aelogr (p1)
+ }
+
+ # Compute the number of minor ticks. If we are log scaling there
+ # are either no minor ticks or 8 minor ticks. If the scaling is
+ # linear the tick placement algorithm is used to compute the best
+ # number of minor ticks, using GL_NMINOR as a close estimate. If
+ # NMINOR is negative automatic tick selection is disabled and exactly
+ # abs(NMINOR) ticks will be drawn. If NMINOR is zero no minor ticks
+ # are drawn.
+
+ if (GL_NMINOR(ap) == 0) # no minor ticks
+ nminor = 0
+ else if (logflag == YES) # log scaling
+ nminor = 8
+ else {
+ minor_step = glb_minorstep (tick1, tick1+step, GL_NMINOR(ap))
+ nminor = nint (abs (step / minor_step)) - 1
+ }
+
+ AX_NMINOR(ax1) = nminor
+ AX_NMINOR(ax2) = nminor
+
+ # Compute the step size in world coords between minor ticks and the
+ # number of minor ticks to be drawn initially until the first major
+ # tick (tick1) is reached. Note that for ELOG scaling the minor
+ # step size and number of minor ticks are different in the range
+ # +-10 (which is linear) than elsewhere, but we ignore that here.
+
+ if (scaling == LINEAR) {
+ minor_step = step / (nminor + 1)
+ AX_INLEFT(ax1) = abs (int ((wctick - wcp1) / minor_step))
+ } else {
+ t1 = nint (tick1)
+ t2 = nint (tick1 + step)
+ if (scaling == LOG)
+ minor_step = (10.0 ** t2 - 10.0 ** t1) / 9.
+ else
+ minor_step = (aelogr(real(t2)) - aelogr(real(t1))) / 9.
+ if (nminor == 0)
+ minor_step = minor_step * 9.
+ AX_INLEFT(ax1) = 0
+ }
+
+ AX_INLEFT(ax2) = AX_INLEFT(ax1)
+
+ # Set KSTEP, the adjustment to the step size at each major tick. This
+ # is always 1.0 if the scale is linear. Set KSTEP to negative if ELOG
+ # scaling, to tell the drawing code to invert kstep (.1->10 or 10->.1)
+ # when passing through the origin (necessary for ELOG scaling). The
+ # sign is not otherwise significant. If heading toward the origin
+ # initially then KSTEP is inverted for ELOG scaling vs LOG scaling.
+
+ if (scaling == LINEAR) {
+ AX_IKSTEP(ax1) = 1.0
+ } else if (scaling == ELOG) {
+ tval = p1
+ if (abs (tval + step) > abs(t1))
+ AX_IKSTEP(ax1) = -10.0
+ else
+ AX_IKSTEP(ax1) = -0.1
+ } else
+ AX_IKSTEP(ax1) = 10.0 ** step
+ AX_IKSTEP(ax2) = AX_IKSTEP(ax1)
+
+ # Set those parameters which differ depending on whether the axis is
+ # horizontal or vertical.
+
+ if (angle == 0) {
+ AX_TICK1(ax1,1) = wctick - (AX_INLEFT(ax1) * minor_step)
+ AX_TICK1(ax2,1) = wctick - (AX_INLEFT(ax2) * minor_step)
+
+ if (GL_SETAXISPOS(ap) == YES) {
+ AX_TICK1(ax1,2) = GL_AXISPOS1(ap)
+ AX_TICK1(ax2,2) = GL_AXISPOS2(ap)
+ } else {
+ AX_TICK1(ax1,2) = WCS_WY1(w)
+ AX_TICK1(ax2,2) = WCS_WY2(w)
+ }
+
+ AX_ISTEP(ax1,1) = minor_step
+ AX_ISTEP(ax2,1) = minor_step
+
+ char_height = ggetr (gp, "ch")
+ if (char_height < EPSILON)
+ char_height = DEF_CHARHEIGHT
+ char_height = char_height * GL_TICKLABELSIZE(ap)
+
+ AX_TICKLABELOFFSET(ax2,2) = 0.5 * char_height
+ AX_TICKLABELOFFSET(ax1,2) = -AX_TICKLABELOFFSET(ax2,2)
+
+ # Set gtext format for tick labels.
+ call strcpy ("hj=c,vj=t", AX_TICKLABELPOS(ax1), SZ_FORMAT)
+ call strcpy ("hj=c,vj=b", AX_TICKLABELPOS(ax2), SZ_FORMAT)
+
+ } else {
+ if (GL_SETAXISPOS(ap) == YES) {
+ AX_TICK1(ax1,1) = GL_AXISPOS1(ap)
+ AX_TICK1(ax2,1) = GL_AXISPOS2(ap)
+ } else {
+ AX_TICK1(ax1,1) = WCS_WX1(w)
+ AX_TICK1(ax2,1) = WCS_WX2(w)
+ }
+
+ AX_TICK1(ax1,2) = wctick - (AX_INLEFT(ax1) * minor_step)
+ AX_TICK1(ax2,2) = wctick - (AX_INLEFT(ax2) * minor_step)
+
+ AX_ISTEP(ax1,2) = minor_step
+ AX_ISTEP(ax2,2) = minor_step
+
+ char_width = ggetr (gp, "cw")
+ if (char_width < EPSILON)
+ char_width = DEF_CHARWIDTH
+ char_width = char_width * GL_TICKLABELSIZE(ap)
+
+ AX_TICKLABELOFFSET(ax2,1) = 0.5 * char_width
+ AX_TICKLABELOFFSET(ax1,1) = -AX_TICKLABELOFFSET(ax2,1)
+
+ call strcpy ("hj=r,vj=c", AX_TICKLABELPOS(ax1), SZ_FORMAT)
+ call strcpy ("hj=l,vj=c", AX_TICKLABELPOS(ax2), SZ_FORMAT)
+ }
+
+ # Set the tick parameters that are identical for the two axes and
+ # which do not depend on whether the axis is horizontal or vertical.
+
+ AX_DRAWTICKS(ax1) = GL_DRAWTICKS(ap)
+ AX_DRAWTICKS(ax2) = GL_DRAWTICKS(ap)
+ AX_TICKLABELSIZE(ax1) = GL_TICKLABELSIZE(ap)
+ AX_TICKLABELSIZE(ax2) = GL_TICKLABELSIZE(ap)
+ AX_TICKLABELCOLOR(ax1) = GL_TICKLABELCOLOR(ap)
+ AX_TICKLABELCOLOR(ax2) = GL_TICKLABELCOLOR(ap)
+ AX_TICKCOLOR(ax1) = GL_TICKCOLOR(ap)
+ AX_TICKCOLOR(ax2) = GL_TICKCOLOR(ap)
+ AX_GRIDCOLOR(ax1) = GL_GRIDCOLOR(ap)
+ AX_GRIDCOLOR(ax2) = GL_GRIDCOLOR(ap)
+ AX_AXISLABELSIZE(ax1) = GL_AXISLABELSIZE(ap)
+ AX_AXISLABELSIZE(ax2) = GL_AXISLABELSIZE(ap)
+ AX_AXISLABELCOLOR(ax1) = GL_AXISLABELCOLOR(ap)
+ AX_AXISLABELCOLOR(ax2) = GL_AXISLABELCOLOR(ap)
+ AX_AXISWIDTH(ax1) = GL_AXISWIDTH(ap)
+ AX_AXISWIDTH(ax2) = GL_AXISWIDTH(ap)
+ AX_AXISCOLOR(ax1) = GL_AXISCOLOR(ap)
+ AX_AXISCOLOR(ax2) = GL_AXISCOLOR(ap)
+ AX_MINORWIDTH(ax1) = GL_MINORWIDTH(ap)
+ AX_MINORWIDTH(ax2) = GL_MINORWIDTH(ap)
+ AX_MAJORWIDTH(ax1) = GL_MAJORWIDTH(ap)
+ AX_MAJORWIDTH(ax2) = GL_MAJORWIDTH(ap)
+
+ # Compute the number of digits of precision needed for the tick labels.
+ AX_NDIGITS(ax1) = max (1, gt_ndigits (p1, p2, step))
+ AX_NDIGITS(ax2) = AX_NDIGITS(ax1)
+
+ # If both axes are to be drawn label ticks if enabled. If only one
+ # axis is to be drawn that is the axis that must be labelled.
+
+ if (GL_DRAWAXES(ap) > 0) {
+ AX_LABELTICKS(ax1) = GL_LABELTICKS(ap)
+ AX_LABELTICKS(ax2) = GL_LABELTICKS(ap)
+ }
+ if (GL_DRAWAXES(ap) == 1 || GL_DRAWAXES(ap) == 3)
+ AX_LABELTICKS(ax2) = NO
+ else if (GL_DRAWAXES(ap) == 2)
+ AX_LABELTICKS(ax1) = NO
+
+ # The user may override the tick label format if desired.
+ if (GL_TICKFORMAT(ap) == EOS) {
+ call sprintf (AX_TICKFORMAT(ax1), SZ_FORMAT, "%%0.%dg")
+ call pargi (AX_NDIGITS(ax1) + 1)
+ } else
+ call strcpy (GL_TICKFORMAT(ap), AX_TICKFORMAT(ax1), SZ_FORMAT)
+ call strcpy (AX_TICKFORMAT(ax1), AX_TICKFORMAT(ax2), SZ_FORMAT)
+end
+
+
+# GLB_MINORSTEP -- Determine the step size for the minor ticks. Adapted
+# from a routine by J. Eisenhamer (STScI) which was based on some MONGO code.
+
+real procedure glb_minorstep (x1, x2, nminor)
+
+real x1, x2 #I interval between major ticks
+int nminor #I suggested number of minor ticks, or actual# if neg
+
+int iexp
+real amant, diff, num, range
+
+begin
+ range = abs (x2 - x1)
+ if (nminor < 0)
+ return (range / real (-nminor + 1))
+ else {
+ # Determine magnitude of the intervals.
+ diff = log10 (range / nminor)
+ iexp = int (diff)
+ if (diff < 0)
+ iexp = iexp - 1
+ amant = diff - real(iexp)
+
+ # Determine an appropriate step size.
+ if (amant < 0.15)
+ num = 1.0
+ else if (amant < 0.50)
+ num = 2.0
+ else if (amant < 0.85)
+ num = 5.0
+ else
+ num = 10.0
+
+ return (num * 10.0**iexp)
+ }
+end