summaryrefslogtreecommitdiffstats
path: root/ast/grf3d_pgplot.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 18:52:35 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2019-05-10 18:52:35 (GMT)
commit9ef925b353e71b6b8abd23b59ca1adef488e3a3b (patch)
tree8d0d428ac62291f834ea8927bfa82c115ff1689d /ast/grf3d_pgplot.c
parent0b1addf5643c828955a6add53f2a4f7a7a813e41 (diff)
downloadblt-9ef925b353e71b6b8abd23b59ca1adef488e3a3b.zip
blt-9ef925b353e71b6b8abd23b59ca1adef488e3a3b.tar.gz
blt-9ef925b353e71b6b8abd23b59ca1adef488e3a3b.tar.bz2
upgrade ast 8.7.1
Diffstat (limited to 'ast/grf3d_pgplot.c')
-rw-r--r--ast/grf3d_pgplot.c3414
1 files changed, 0 insertions, 3414 deletions
diff --git a/ast/grf3d_pgplot.c b/ast/grf3d_pgplot.c
deleted file mode 100644
index 3a249e2..0000000
--- a/ast/grf3d_pgplot.c
+++ /dev/null
@@ -1,3414 +0,0 @@
-/*
-* Name:
-* grf3d_pgplot.c
-
-* Purpose:
-* Implement the grf3d interface using the PGPLOT graphics system.
-
-* Description:
-* This file implements the low level 3D graphics functions required
-* by the rest of AST, by calling suitable PGPLOT functions (the
-* FORTRAN PGPLOT interface is used).
-*
-* This file can be used as a template for the development of
-* similar implementations based on other graphics systems.
-*
-* Unlike world coordinates used by the 2D grf interface, the 3D world
-* coordinates used by the grf3D interface are assume to be equally scaled
-* (that is, they are assumed to have the same units). Therefore this
-* module has no equivalent to the astGScales function defined by the
-* 2D grf interface.
-
-* Copyright:
-* Copyright (C) 2007 Science & Technology Facilities Council.
-* All Rights Reserved.
-
-* Licence:
-* This program is free software: you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation, either
-* version 3 of the License, or (at your option) any later
-* version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General
-* License along with this program. If not, see
-* <http://www.gnu.org/licenses/>.
-
-* Authors:
-* DSB: David S. Berry (Starlink)
-
-* History:
-* 20-JUN-2007 (DSB):
-* Original version.
-*/
-
-
-/* Macros */
-/* ====== */
-#define MXDEV 16 /* Max no of concurrent PGPLOT devices */
-#define MXSTRLEN 80 /* Max PGPLOT string length */
-#define CAMERA_OK 123456789 /* Flags that a Camera has been initialised */
-#define TWOPI 6.28318530718 /* 2*PI */
-#define MXSIDE 32 /* Max no of sides in a marker polygon */
-
-
-/* Header files. */
-/* ============= */
-/* AST header files */
-#include "grf3d.h" /* The grf3D interface definition */
-#include "pg3d.h" /* Other public functions in this module */
-#include "f77.h" /* FORTRAN <-> C interface macros (SUN/209) */
-#include "c2f77.h" /* C to FORTRAN interface functions */
-#include "memory.h" /* Memory allocation facilities */
-#include "error.h" /* Error reporting facilities */
-#include "pointset.h" /* Defines AST__BAD */
-#include "ast_err.h" /* AST error codes */
-
-/* System header files */
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <limits.h>
-#include <stdio.h>
-
-
-/* Type definitions. */
-/* ================= */
-/* Structure defining the position and orientation of the camera in 3D
- world coords. This is specific to the PGPLOT implementation. Other
- implementations need not include any equivalent to this structure. */
-typedef struct camera {
- float eye_vector[3];
- float target_vector[3];
- float up_vector[3];
- float w2c_matrix[9];
- float screen_distance;
- int ok_flag;
-} Camera;
-
-
-/* Module variables. */
-/* ================= */
-/* One camera structure for each PGPLOT device identifier. PGPLOT allows
- a maximum of 8 concurrent devices at the moment. Make the array twice
- this size to allow for some future expansion in PGPLOT. Again, this is
- specific to the PGPLOT implementation of the grf3D interface. */
-static Camera cameras[ MXDEV ];
-
-/* Function templates. */
-/* =================== */
-/* Templates for functions that are private to this module. */
-static Camera *getCamera( int );
-static float getCharHeight( void );
-static int Polygon( int, float *, float *, float *, float[3], float[3], float[3], float[3] );
-static int Text( int *, int, float[3], const char *, float[3], float[3], float[3] );
-static int TextCam( Camera *, float[3], float[3], float[3], float[3] );
-static int TxExt( int *, int, float[3], const char *, float[3], float[3], float[3], float *, float *, float *, float[3] );
-static int getTextAxes( float[3], float[3], float[3], const char *, float[3], float[3], float[3], char[3] );
-static int transform( Camera *, int, float *, float *, float *, float *, float * );
-static int vectorNorm( float * );
-static float vectorModulus( float * );
-static void getSymbolList( const char *, int, int *, int * );
-static void vectorProduct( float *, float *, float * );
-static float dotProduct( float *, float * );
-static void vectorSub( float *, float *, float * );
-
-/* Templates for private functions that wrap PGPLOT Fortran routines. */
-static void ccgrsyds( int *, int *, const char *, int, int );
-static void ccgrsymk( int, int, int * );
-static void ccgrsyxd( int, int *, int * );
-static void ccpgline( int, float[], float[] );
-static void ccpgpoly( int, float[], float[] );
-static void ccpgqcf( int * );
-static void ccpgqcf(int *);
-static void ccpgqch( float * );
-static void ccpgqci( int * );
-static void ccpgqclp( int * );
-static void ccpgqid( int * );
-static void ccpgqls( int * );
-static void ccpgqlw( int * );
-static void ccpgqvsz( int, float *, float *, float *, float * );
-static void ccpgqwin( float *, float *, float *, float * );
-static void ccpgscf( int );
-static void ccpgsch( float );
-static void ccpgsci( int );
-static void ccpgsclp( int );
-static void ccpgsls( int );
-static void ccpgslw( int );
-static void ccpgswin( float, float, float, float );
-static void ccpgupdt( void );
-
-
-/* Templates for Fortran PGPLOT routines needed by this module. */
-F77_SUBROUTINE(grsyds)( INTEGER_ARRAY(list), INTEGER(nlist), CHARACTER(text), INTEGER(font) TRAIL(text) );
-F77_SUBROUTINE(grsymk)( INTEGER(type), INTEGER(font), INTEGER(symbol) );
-F77_SUBROUTINE(grsyxd)( INTEGER(symbol), INTEGER_ARRAY(xygrid), INTEGER(unused) );
-F77_SUBROUTINE(pgline)( INTEGER(N), REAL_ARRAY(X), REAL_ARRAY(Y) );
-F77_SUBROUTINE(pgpoly)( INTEGER(N), REAL_ARRAY(X), REAL_ARRAY(Y) );
-F77_SUBROUTINE(pgqcf)( INTEGER(ival) );
-F77_SUBROUTINE(pgqch)( REAL(rval) );
-F77_SUBROUTINE(pgqci)( INTEGER(ival) );
-F77_SUBROUTINE(pgqclp)( INTEGER(clip) );
-F77_SUBROUTINE(pgqid)( INTEGER(id) );
-F77_SUBROUTINE(pgqls)( INTEGER(ival) );
-F77_SUBROUTINE(pgqlw)( INTEGER(ival) );
-F77_SUBROUTINE(pgqvsz)( INTEGER(units), REAL(x1), REAL(x2), REAL(y1), REAL(y2) );
-F77_SUBROUTINE(pgqwin)( REAL(wx1), REAL(wx2), REAL(wy1), REAL(wy2) );
-F77_SUBROUTINE(pgscf)( INTEGER(ival) );
-F77_SUBROUTINE(pgsch)( REAL(rval) );
-F77_SUBROUTINE(pgsci)( INTEGER(ival) );
-F77_SUBROUTINE(pgsclp)( INTEGER(clip) );
-F77_SUBROUTINE(pgsls)( INTEGER(ival) );
-F77_SUBROUTINE(pgslw)( INTEGER(ival) );
-F77_SUBROUTINE(pgswin)( REAL(X1), REAL(X2), REAL(Y1), REAL(Y2) );
-F77_SUBROUTINE(pgupdt)( void );
-
-
-/* Public functions defined by the grf3D interface. */
-/* ================================================ */
-/* All implementations of the grf3d interface must provide implementations
- of all the functions in this block. The corresponding templates are in
- grf3d.h */
-
-
-int astG3DAttr( int attr, double value, double *old_value, int prim ){
-/*
-*+
-* Name:
-* astG3DAttr
-
-* Purpose:
-* Enquire or set a 3D graphics attribute value.
-
-* Synopsis:
-* #include "grf3d.h"
-* int int astG3DAttr( int attr, double value, double *old_value, int prim )
-
-* Description:
-* This function returns the current value of a specified 3D graphics
-* attribute, and optionally establishes a new value. The supplied
-* value is converted to an integer value if necessary before use.
-
-* Parameters:
-* attr
-* An integer value identifying the required attribute. The
-* following symbolic values are defined in grf3d.h:
-*
-* GRF__STYLE - Line style.
-* GRF__WIDTH - Line width.
-* GRF__SIZE - Character and marker size scale factor.
-* GRF__FONT - Character font.
-* GRF__COLOUR - Colour index.
-* value
-* A new value to store for the attribute. If this is AST__BAD
-* no value is stored.
-* old_value
-* A pointer to a double in which to return the attribute value.
-* If this is NULL, no value is returned.
-* prim
-* The sort of graphics primitive to be drawn with the new attribute.
-* Identified by the following values defined in grf.h:
-* GRF__LINE
-* GRF__MARK
-* GRF__TEXT
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-
-*-
-*/
-
- int ival;
- float rval, dx, dy, deflw, x1, x2, y1, y2;
-
-/* If required retrieve the current line style, and set a new line style. */
- if( attr == GRF__STYLE ){
- ccpgqls( &ival );
- if( old_value ) *old_value = (double) ival;
-
- if( value != AST__BAD ){
- ival = (int) ( value + 0.5 );
- if( value < 0.0 ) ival -= 1;
-
- ival = ( ival - 1 ) % 5;
- ival += ( ival < 0 ) ? 6 : 1;
-
- ccpgsls( ival );
- }
-
-/* If required retrieve the current line width, and set a new line width.
- Line width is stored in Plot as a scale factor (1.0 for the default line
- width which is a fixed fraction of the diagonal of the view surface), but
- pgplot stores it in units of 0.005 of an inch. */
- } else if( attr == GRF__WIDTH ){
-
-/* Get the bounds of the view surface in inches. */
- ccpgqvsz( 1, &x1, &x2, &y1, &y2 );
-
-/* Find the default line width in inches (i.e. 0.0005 of the length
- of the view surface diagonal). */
- dx = ( x1 - x2 );
- dy = ( y1 - y2 );
- deflw = 0.0005*sqrt( (double )( dx*dx + dy*dy ) );
-
-/* Get the current pgplot line width in units of 0.005 of an inch. */
- ccpgqlw( &ival );
-
-/* If required, return the factor by which this exceeds the default line
- width found above. */
- if( old_value ) *old_value = (double)( ival )/( 200.0 * deflw );
-
-/* If a new line width has been provided, the pgplot line width needs to
- be set to the corresponding absolute value. */
- if( value != AST__BAD ){
- ival = (int) ( 200.0*value*deflw );
- if( ival < 1 ) {
- ival = 1;
- } else if( ival > 201 ){
- ival = 201;
- }
- ccpgslw( ival );
- }
-
-/* If required retrieve the current character size, and set a new size.
- The attribute value should be a factor by which to multiply the
- default character size. */
- } else if( attr == GRF__SIZE ){
- ccpgqch( &rval );
- if( old_value ) *old_value = (double) rval;
-
- if( value != AST__BAD ){
- ccpgsch( (float) value );
- }
-
-/* If required retrieve the current character font, and set a new font. */
- } else if( attr == GRF__FONT ){
- ccpgqcf( &ival );
- if( old_value ) *old_value = (double) ival;
-
- if( value != AST__BAD ){
- ival = (int) ( value + 0.5 );
- if( value < 0.0 ) ival -= 1;
-
- ival = ( ival - 1 ) % 4;
- ival += ( ival < 0 ) ? 5 : 1;
- ccpgscf( ival );
- }
-
-/* If required retrieve the current colour index, and set a new colour
- index. */
- } else if( attr == GRF__COLOUR ){
- ccpgqci( &ival );
- if( old_value ) *old_value = (double) ival;
-
- if( value != AST__BAD ){
- ival = (int) ( value + 0.5 );
- if( ival < 0 ) ival = 1;
- ccpgsci( ival );
- }
-
-/* Give an error message for any other attribute value. */
- } else {
- astError( AST__GRFER, "astG3DAttr: Unknown graphics attribute '%d' "
- "requested.", attr );
- return 0;
- }
-
-/* Return. */
- return 1;
-}
-
-int astG3DCap( int cap, int value ){
-/*
-*+
-* Name:
-* astG3DCap
-
-* Purpose:
-* Indicate if this grf3d module has a given capability.
-
-* Synopsis:
-* #include "grf3d.h"
-* int astG3DCap( int cap, int value )
-
-* Description:
-* This function is called by the AST Plot class to determine if the
-* grf3d module has a given capability, as indicated by the "cap"
-* argument.
-
-* Parameters:
-* cap
-* The capability being inquired about. This will be one of the
-* following constants defined in grf3d.h:
-*
-* GRF3D__ESC: This function should return a non-zero value if the
-* astG3DText and astG3DTxExt functions can recognise and interpret
-* graphics escape sequences within the supplied string. These
-* escape sequences are described below. Zero should be returned
-* if escape sequences cannot be interpreted (in which case the
-* Plot class will interpret them itself if needed). The supplied
-* "value" argument should be ignored only if escape sequences cannot
-* be interpreted by astG3DText and astG3DTxExt. Otherwise, "value"
-* indicates whether astG3DText and astG3DTxExt should interpret escape
-* sequences in subsequent calls. If "value" is non-zero then
-* escape sequences should be interpreted by astG3DText and
-* astG3DTxExt. Otherwise, they should be drawn as literal text.
-
-* Returned Value:
-* The return value, as described above. Zero should be returned if
-* the supplied capability is not recognised.
-
-* Escape Sequences:
-* Escape sequences are introduced into the text string by a percent
-* "%" character. The following escape sequences are currently recognised
-* ("..." represents a string of one or more decimal digits):
-*
-* %% - Print a literal "%" character (type GRF__ESPER ).
-*
-* %^...+ - Draw subsequent characters as super-scripts. The digits
-* "..." give the distance from the base-line of "normal"
-* text to the base-line of the super-script text, scaled
-* so that a value of "100" corresponds to the height of
-* "normal" text (type GRF__ESSUP ).
-* %^+ - Draw subsequent characters with the normal base-line.
-*
-* %v...+ - Draw subsequent characters as sub-scripts. The digits
-* "..." give the distance from the base-line of "normal"
-* text to the base-line of the sub-script text, scaled
-* so that a value of "100" corresponds to the height of
-* "normal" text (type GRF__ESSUB ).
-*
-* %v+ - Draw subsequent characters with the normal base-line
-* (equivalent to %^+).
-*
-* %>...+ - Leave a gap before drawing subsequent characters.
-* The digits "..." give the size of the gap, scaled
-* so that a value of "100" corresponds to the height of
-* "normal" text (type GRF__ESGAP ).
-*
-* %<...+ - Move backwards before drawing subsequent characters.
-* The digits "..." give the size of the movement, scaled
-* so that a value of "100" corresponds to the height of
-* "normal" text (type GRF_ESBAC).
-*
-* %s...+ - Change the Size attribute for subsequent characters. The
-* digits "..." give the new Size as a fraction of the
-* "normal" Size, scaled so that a value of "100" corresponds
-* to 1.0 (type GRF__ESSIZ ).
-*
-* %s+ - Reset the Size attribute to its "normal" value.
-*
-* %w...+ - Change the Width attribute for subsequent characters. The
-* digits "..." give the new width as a fraction of the
-* "normal" Width, scaled so that a value of "100" corresponds
-* to 1.0 (type GRF__ESWID ).
-*
-* %w+ - Reset the Size attribute to its "normal" value.
-*
-* %f...+ - Change the Font attribute for subsequent characters. The
-* digits "..." give the new Font value (type GRF__ESFON ).
-*
-* %f+ - Reset the Font attribute to its "normal" value.
-*
-* %c...+ - Change the Colour attribute for subsequent characters. The
-* digits "..." give the new Colour value (type GRF__ESCOL ).
-*
-* %c+ - Reset the Colour attribute to its "normal" value.
-*
-* %t...+ - Change the Style attribute for subsequent characters. The
-* digits "..." give the new Style value (type GRF__ESSTY ).
-*
-* %t+ - Reset the Style attribute to its "normal" value.
-*
-* %- - Push the current graphics attribute values onto the top of
-* the stack - see "%+" (type GRF__ESPSH).
-*
-* %+ - Pop attributes values of the top the stack - see "%-". If
-* the stack is empty, "normal" attribute values are restored
-* (type GRF__ESPOP).
-*
-* The astFindEscape function (in libast.a) can be used to locate escape
-* sequences within a text string. It has the following signature:
-*
-* #include "plot.h"
-* int astFindEscape( const char *text, int *type, int *value, int *nc )
-*
-* Parameters:
-* text
-* Pointer to the string to be checked.
-* type
-* Pointer to a location at which to return the type of escape
-* sequence. Each type is identified by a symbolic constant defined
-* in grf.h and is indicated in the above section. The returned value
-* is undefined if the supplied text does not begin with an escape
-* sequence.
-* value
-* Pointer to a lcation at which to return the integer value
-* associated with the escape sequence. All usable values will be
-* positive. Zero is returned if the escape sequence has no associated
-* integer. A value of -1 indicates that the attribute identified by
-* "type" should be reset to its "normal" value (as established using
-* the astG3DAttr function, etc). The returned value is undefined if
-* the supplied text does not begin with an escape sequence.
-* nc
-* Pointer to a location at which to return the number of
-* characters read by this call. If the text starts with an escape
-* sequence, the returned value will be the number of characters in
-* the escape sequence. Otherwise, the returned value will be the
-* number of characters prior to the first escape sequence, or the
-* length of the supplied text if no escape sequence is found.
-
-* Returned Value:
-* A non-zero value is returned if the supplied text starts with a
-* graphics escape sequence, and zero is returned otherwise.
-
-*-
-*/
-
- return 0;
-}
-
-int astG3DFlush( void ){
-/*
-*+
-* Name:
-* astG3DFlush
-
-* Purpose:
-* Flush all pending graphics to the output device.
-
-* Synopsis:
-* #include "grf3d.h"
-* int astG3DFlush( void )
-
-* Description:
-* This function ensures that the display device is up-to-date,
-* by flushing any pending graphics to the output device.
-
-* Parameters:
-* None.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-*-
-*/
-
- ccpgupdt();
- return 1;
-}
-
-int astG3DLine( int n, float *x, float *y, float *z ){
-/*
-*+
-* Name:
-* astG3DLine
-
-* Purpose:
-* Draw a polyline (i.e. a set of connected lines).
-
-* Synopsis:
-* #include "grf3d.h"
-* int astG3DLine( int n, float *x, float *y, float *z )
-
-* Description:
-* This function displays lines joining the given positions.
-
-* Parameters:
-* n
-* The number of positions to be joined together.
-* x
-* A pointer to an array holding the "n" x values.
-* y
-* A pointer to an array holding the "n" y values.
-* z
-* A pointer to an array holding the "n" z values.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - A camera must have been established prior to calling this
-* function using either astG3DSetCamera or astG3DAutoCamera.
-* - Nothing is done if "n" is less than 2, or if a NULL pointer is
-* given for either "x", "y" or "z".
-
-*-
-*/
-
-/* Local Variables: */
- int clip;
- int result = 0;
- float *h, *r;
-
-/* Do nothing if we have less than 2 points, but do not indicate an error. */
- if( n < 2 ){
- result = 1;
-
-/* Check the pointers. */
- } else if( x && y && z ) {
-
-/* Save the current clipping flag, and ensure clipping is off. */
- ccpgqclp( &clip );
- ccpgsclp( 0 );
-
-/* Allocate work space for the 2D world coordinate positions. */
- h = astMalloc( sizeof( float )*(size_t) n );
- r = astMalloc( sizeof( float )*(size_t) n );
- if( astOK ) {
-
-/* Convert the supplied points from 3D world coordinates to 2D world
- (i.e. screen) coordinates. If succesful, plot the lines. */
- if( transform( NULL, n, x, y, z, h, r ) ) {
- ccpgline( n, (float *) h, (float *) r );
- result = 1;
- }
- }
-
-/* Free work space. */
- h = astFree( h );
- r = astFree( r );
-
-/* Re-instate original clipping flag. */
- ccpgsclp( clip );
-
- }
- return result;
-}
-
-int astG3DMark( int n, float *x, float *y, float *z, int type,
- float norm[3] ){
-/*
-*+
-* Name:
-* astG3DMark
-
-* Purpose:
-* Draw a set of markers.
-
-* Synopsis:
-* #include "grf.h"
-* int astG3DMark( int n, float *x, float *y, float *z, int type,
-* float norm[3] )
-
-* Description:
-* This function draws markers centred at the given positions, on a
-* plane with a specified normal vector.
-
-* Parameters:
-* n
-* The number of markers to draw.
-* x
-* A pointer to an array holding the "n" x values.
-* y
-* A pointer to an array holding the "n" y values.
-* z
-* A pointer to an array holding the "n" z values.
-* type
-* An integer which can be used to indicate the type of marker symbol
-* required. See the description of routine PGPT in the PGPLOT manual.
-* norm
-* The (x,y,z) components of a vector that is normal to the plane
-* containing the marker. The given vector passes through the marker
-* from the back to the front. If all components of this vector are
-* zero, then a normal vector pointing from the position of the
-* first marker towards the camera eye is used.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Nothing is done if "n" is less than 1, or if a NULL pointer is
-* given for "x", "y" or "z".
-
-*-
-*/
-
-/* local Variables: */
- char just[3];
- float ref[3];
- float up[3];
- float tx[3], ty[3], tz[3];
- float vx[ MXSIDE ], vy[ MXSIDE ], vz[ MXSIDE ];
- float ch, ang, dang;
- int clip;
- int font;
- int i;
- int nlist;
- int symnum;
- int ns;
-
-/* Return if any of the coordinate pointers is NULL. */
- if( !x || !y || !z ) return 1;
-
-/* Initialise */
- ns = 0;
-
-/* Unless the "norm" vector is parallel to the z axis, we use an up vector
- that is parallel to the z axis. Otherwise we use an up vector paralle
- to the x axis. */
- if( norm[ 0 ] != 0.0 || norm[ 1 ] != 0.0 ) {
- up[ 0 ] = 0.0;
- up[ 1 ] = 0.0;
- up[ 2 ] = 1.0;
- } else {
- up[ 0 ] = 1.0;
- up[ 1 ] = 0.0;
- up[ 2 ] = 0.0;
- }
-
-/* Create unit vectors along the three axes of the text plane
- coordinate system. */
- ref[ 0 ] = x[ 0 ];
- ref[ 1 ] = y[ 0 ];
- ref[ 2 ] = z[ 0 ];
- if( !getTextAxes( ref, up, norm, "CC", tx, ty, tz, just ) ) return 0;
-
-/* Calculate the pgplot symbol number for the given marker type. */
- if( type > 0 ) {
- if( type > 127 ) {
- symnum = type;
- } else {
- ccpgqcf( &font );
- ccgrsymk( type, font, &symnum );
- }
-
- } else if( type > -3 ) {
- getSymbolList( ".", 1, &symnum, &nlist );
-
-/* Regular polygons - create an array of text plane coordinates for the
- vertices of the polygon. */
- } else {
- symnum = type;
-
-/* Get the character height in world coordinate units. A PGPLOT
- character height of 1.0 corresponds to 1/40 of the 2D window height. */
- ch = getCharHeight();
-
-/* Limit the number of sides that can be produced. */
- ns = -type;
- if( ns > MXSIDE ) ns = MXSIDE;
-
-/* Calculate the angle subtended by each edge of the polygon. */
- dang = TWOPI/ns;
- ang = 0.0;
-
-/* Loop round each vertex. */
- for( i = 0; i < ns; i++ ) {
- vx[ i ] = ch*sin( ang );
- vy[ i ] = ch*cos( ang );
- vz[ i ] = 0.0;
- ang += dang;
- }
- }
-
-/* Save the current clipping flag, and ensure clipping is off. */
- ccpgqclp( &clip );
- ccpgsclp( 0 );
-
-/* Draw each marker in turn. */
- for( i = 0; i < n; i++ ) {
-
-/* Store the centre world coords */
- ref[ 0 ] = x[ i ];
- ref[ 1 ] = y[ i ];
- ref[ 2 ] = z[ i ];
-
-/* Draw the symbol, and return if anything goes wrong. */
- if( symnum >= 0 ) {
- if( !Text( &symnum, 1, ref, "CC", tx, ty, tz ) ) return 0;
-
- } else {
- if( !Polygon( ns, vx, vy, vz, ref, tx, ty, tz ) ) return 0;
-
- }
-
- }
-
-/* Re-instate original clipping flag. */
- ccpgsclp( clip );
-
-/* If we arrive here we have been succesful, so return a non-zero value. */
- return 1;
-}
-
-int astG3DQch( float *ch ){
-/*
-*+
-* Name:
-* astG3DQch
-
-* Purpose:
-* Return the character height in world coordinates.
-
-* Synopsis:
-* #include "grf3d.h"
-* int astG3DQch( float *ch )
-
-* Description:
-* This function returns the height of characters drawn using astG3DText.
-
-* Parameters:
-* ch
-* A pointer to the double which is to receive the height of
-* characters drawn with astG3DText.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Since the 3D world coordinate axes are assumed to be equally
-* scaled, the height of text in world coordinate units is independent
-* of the orientation of the text. Therefore, this function returns
-* only one height value, unlike the equivalent 2D astGQch function
-* that returns two heights.
-*-
-*/
- *ch = getCharHeight();
- return 1;
-}
-
-int astG3DText( const char *text, float ref[3], const char *just, float up[3],
- float norm[3] ){
-/*
-*+
-* Name:
-* astG3DText
-
-* Purpose:
-* Draw a character string.
-
-* Synopsis:
-* #include "grf3d.h"
-* int astG3DText( const char *text, float ref[3], const char *just,
-* float up[3], float norm[3] )
-
-* Description:
-* This function displays a character string at a given position
-* on a given plane in 3D world coords, using a specified
-* justification and up-vector.
-
-* Parameters:
-* text
-* Pointer to a null-terminated character string to be displayed.
-* ref
-* The reference (x,y,z) coordinates.
-* just
-* A character string which specifies the location within the
-* text string which is to be placed at the reference position
-* given by x and y. The first character may be 'T' for "top",
-* 'C' for "centre", or 'B' for "bottom", and specifies the
-* vertical location of the reference position. Note, "bottom"
-* corresponds to the base-line of normal text. Some characters
-* (eg "y", "g", "p", etc) descend below the base-line. The second
-* character may be 'L' for "left", 'C' for "centre", or 'R'
-* for "right", and specifies the horizontal location of the
-* reference position. If the string has less than 2 characters
-* then 'C' is used for the missing characters.
-* up
-* The (x,y,z) up-vector for the text. The actual up vector used is
-* the projection of the supplied vector onto the plane specified by
-* "norm".
-* norm
-* The (x,y,z) components of a vector that is normal to the plane
-* containing the text. The given vector passes through the text
-* from the back to the front. If all components of this vector are
-* zero, then a normal vector pointing towards the camera eye is used.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - This routine does not recognise PGPLOT escape sequences.
-* - A NULL value for "just" causes a value of "CC" to be used.
-*-
-*/
-
-/* Local Constants: */
-#define MXLEN 256
-
-/* Local Variables: */
- char newjust[3];
- float tx[3], ty[3], tz[3];
- int list[ MXLEN ];
- int nlist;
-
-/* Convert the supplied string into a list of PGPLOT symbol numbers */
- getSymbolList( text, MXLEN, &nlist, list );
-
-/* Create unit vectors along the three axes of the text plane
- coordinate system. */
- if( !getTextAxes( ref, up, norm, just, tx, ty, tz, newjust ) ) return 0;
-
-/* Draw the text. */
- return Text( list, nlist, ref, newjust, tx, ty, tz );
-
-/* Clear local constants. */
-#undef MXLEN
-}
-
-int astG3DTxExt( const char *text, float ref[3], const char *just,
- float up[3], float norm[3], float *xb, float *yb,
- float *zb, float bl[3] ){
-/*
-*+
-* Name:
-* astG3DTxExt
-
-* Purpose:
-* Get the extent of a character string.
-
-* Synopsis:
-* #include "grf3d.h"
-* int astG3DTxExt( const char *text, float ref[3], const char *just,
-* float up[3], float norm[3], float *xb, float *yb,
-* float *zb, float bl[3] )
-
-* Description:
-* This function returns the corners of a box which would enclose the
-* supplied character string if it were displayed using astG3DText.
-*
-* The returned box INCLUDES any leading or trailing spaces.
-
-* Parameters:
-* text
-* Pointer to a null-terminated character string to be displayed.
-* ref
-* The reference (x,y,z) coordinates.
-* just
-* A character string which specifies the location within the
-* text string which is to be placed at the reference position
-* given by x and y. The first character may be 'T' for "top",
-* 'C' for "centre", 'B' for "baseline", or "M" for "bottom", and
-* specifies the vertical location of the reference position. Note,
-* "baseline" corresponds to the base-line of normal text. Some
-* characters (eg "y", "g", "p", etc) descend below the base-line,
-* and so "M" and "B" will produce different effects for such
-* characters. The second character may be 'L' for "left", 'C' for
-* "centre", or 'R' for "right", and specifies the horizontal
-* location of the reference position. If the string has less than
-* 2 characters then 'C' is used for the missing characters.
-* up
-* The (x,y,z) up-vector for the text. The actual up vector used is
-* the projection of the supplied vector onto the plane specified by
-* "norm".
-* norm
-* The (x,y,z) components of a vector that is normal to the plane
-* containing the text. The given vector passes through the text
-* from the back to the front. If all components of this vector are
-* zero, then a normal vector pointing towards the camera eye is used.
-* xb
-* An array of 4 elements in which to return the x coordinate of
-* each corner of the bounding box.
-* yb
-* An array of 4 elements in which to return the y coordinate of
-* each corner of the bounding box.
-* zb
-* An array of 4 elements in which to return the z coordinate of
-* each corner of the bounding box.
-* bl
-* The 3D world coordinates at the left hand end of the text
-* baseline.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - The order of the corners is anti-clockwise starting at the
-* bottom left when viewing the text normally (i.e. face on).
-* - This routine does not recognise PGPLOT escape sequences.
-* - A NULL value for "just" causes a value of "CC" to be used.
-*-
-*/
-
-/* Local Constants: */
-#define MXLEN 256
-
-/* Local Variables: */
- char newjust[3];
- int i;
- int list[ MXLEN ];
- int nlist;
- float tx[3], ty[3], tz[3];
-
-/* Initialise the returned values to indicate no box available. */
- for( i = 0; i < 4; i++ ){
- xb[ i ] = 0.0;
- yb[ i ] = 0.0;
- zb[ i ] = 0.0;
- }
-
-/* Convert the supplied string into a list of symbol numbers */
- getSymbolList( text, MXLEN, &nlist, list );
-
-/* Create unit vectors along the three axes of the text plane
- coordinate system. */
- if( !getTextAxes( ref, up, norm, just, tx, ty, tz, newjust ) ) return 0;
-
-/* Find the bounding box of this list of symbols. */
- return TxExt( list, nlist, ref, newjust, tx, ty, tz, xb, yb, zb, bl );
-
-/* Clear local constants. */
-#undef MXLEN
-}
-
-
-/* Public functions specific to this PGPLOT implementation. */
-/* ======================================================== */
-/* Other implementations of the grf3d interface can ignore the following
- functions. They provide control of the 3D view. */
-
-int PG3DSetCamera( float eye[3], float target[3], float up[3], float screen ){
-/*
-*+
-* Name:
-* PG3DSetCamera
-
-* Purpose:
-* Store new camera settings for the current PGPLOT device.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DSetCamera( float eye[3], float target[3], float up[3],
-* float screen )
-
-* Description:
-* This function stores new camera settings for the current PGPLOT
-* device.
-*
-* A "camera" describes the projection of the 3D world coordinate
-* space onto a 2D "screen". This screen corresponds to the 2D viewing
-* surface used by PGPLOT. The 2D window used by PGPLOT (as set by
-* PGSWIN, etc) defines the bounds of the screen area that is visible
-* in the PGPLOT viewport.
-*
-* The 3D world coordinate axes (x,y,z) are such that if "z" is
-* vertically upwards and "x" points to the right, then "y" goes
-* out of the paper away from you. All 3 axes are assume to have equal
-* scale.
-*
-* A camera defines a second set of 3D axes (called "(u,v,w)") with
-* origin at the 3D world coordinates given by "eye":
-*
-* - the "w" axis points towards the position given by "target"
-* - the "v" axis is perpendicular to the "w" axis and is in the plane
-* spanned by the "w" axis and the supplied "up" vector
-* - the "u" axis is perpendicular to both "w" and "v" and points to
-* the left when looking from the eye along the w axis with the v
-* axis upwards
-*
-* Thus the "v" axis is parallel to "vertically up" on the 2D screen,
-* "u" is parallel to "horizontally to the left", and "w" is
-* perpendicular to the screen, pointing towards the target.
-*
-* The screen is a plane perpendicular to the "w" axis, at the "w" axis
-* value given by "screen". A 2D cartesian coordinate system (h,r) is
-* defined on the screen, with origin at the point where the "w" axis
-* intersects the screen. The "h" (horizontal) axis is parallel to the
-* "u" axis but points in the opposite direction (to the left), and the
-* "r" (vertical) axis is parallel to the "v" axis. The (h,r) system is
-* taken to be the same as the PGPLOT 2D world coordinate system, and
-* PGSWIN can therefore be used to specify the rectangular area on the
-* screen that is mapped onto the PGPLOT viewport.
-*
-* It is assumed that all axes (x,y,z), (u,v,w) and (h,r) are measured
-* in the same units.
-
-* Parameters:
-* eye
-* The position vector of the camera's "eye", in 3D world coordinates.
-* target
-* The position vector of a point in 3D world coordinates that is
-* at the centre of the camera's view. In other words, the camera is
-* looking towards this point. Zero will be returned if the target
-* is the same position as the eye.
-* up
-* A vector in 3D world coordinates that will appear vertically
-* upwards when projected onto the screen. Zero will be returned if
-* the up vector has zero length or is parallel to the line joining
-* the eye and the target.
-* screen
-* The distance from the camera's eye to the projection screen. If
-* this is zero, then an orthographic projection is used.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- float *u, *v, *w;
- int result = 0;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 0 );
- if( cam ) {
- result = 1;
-
-/* Store the supplied values in the camera. */
- memcpy( cam->target_vector, target, 3*sizeof( float ) );
- memcpy( cam->eye_vector, eye, 3*sizeof( float ) );
- cam->screen_distance = screen;
-
-/* Get pointers to the three rows of the w2c_matrix. This is a 3x3 matrix that
- rotates vectors in the (x,y,z) system into vectors in the (u,v,w)
- system. Each row in the matrix is a unit vector along the u, v or w
- axes. */
- u = cam->w2c_matrix;
- v = u + 3;
- w = v + 3;
-
-/* The "w" axis points form the eye to the target, so get the vector from
- the eye to the target and normalise it. */
- vectorSub( target, eye, w );
- if( ! vectorNorm( w ) ) result = 0;
-
-/* The "v" vector is in the plane spanned by the "w" axis and the "up"
- vector. Get the normal to this plane, storing the result temporarily
- in the "u" vector. . */
- vectorProduct( w, up, u );
-
-/* The "v" vector is normal to the vector found above and is also normal
- to the "w" axis. Get this vector and normalise it. */
- vectorProduct( u, w, v );
- if( ! vectorNorm( v ) ) result = 0;
-
-/* The "u" vector is perpendicualr to both the "w" and "v" vectors. */
- vectorProduct( v, w, u );
- if( ! vectorNorm( u ) ) result = 0;
-
-/* Use "v" as the stored up vector (the supplied "up" vector is not
- necesarily the same as "v"). */
- memcpy( cam->up_vector, v, 3*sizeof( float ) );
-
-/* Se a flag that indicates that the Camera is usable. */
- cam->ok_flag = result ? CAMERA_OK : CAMERA_OK/2;
- }
-
- return result;
-}
-
-int PG3DGetCamera( float eye[3], float target[3], float up[3], float *screen ){
-/*
-*+
-* Name:
-* PG3DGetCamera
-
-* Purpose:
-* Get the current camera settings for the current PGPLOT device.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DGetCamera( float eye[3], float target[3], float up[3],
-* float *screen )
-
-* Description:
-* This function retrieves the current camera settings for the current
-* PGPLOT device. See PG3DSetCamera for more info. Any of the supplied
-* parameters can be set to NULL if the information is not needed.
-
-* Parameters:
-* eye
-* The position vector of the camera's "eye", in 3D world coordinates.
-* target
-* The position vector of a point in 3D world coordinates that is
-* at the centre of the camera's view. In other words, the camera is
-* looking towards this point. Zero will be returned if the target
-* is the same position as the eye.
-* up
-* A vector in 3D world coordinates that will appear vertically
-* upwards when projected onto the screen. Zero will be returned if
-* the up vector has zero length or is parallel to the line joining
-* the eye and the target.
-* screen
-* The distance from the camera's eye to the projection screen. If
-* this is zero, then an orthographic projection is used.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 0 );
- if( cam ) {
- result = 1;
-
-/* Copy the current values into the supplied arrays. */
- if( target ) memcpy( target, cam->target_vector, 3*sizeof( float ) );
- if( eye) memcpy( eye, cam->eye_vector, 3*sizeof( float ) );
- if( up ) memcpy( up, cam->up_vector, 3*sizeof( float ) );
- if( screen ) *screen = cam->screen_distance;
- result = ( cam->ok_flag == CAMERA_OK );
- }
-
- return result;
-}
-
-int PG3DSetEye( float eye[3] ){
-/*
-*+
-* Name:
-* PG3DSetEye
-
-* Purpose:
-* Store a new camera eye position for the current PGPLOT device.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DSetEye( float eye[3] )
-
-* Description:
-* This function modifies the camera eye position for the current
-* PGPLOT device. Other camera settings are left unchanged. See
-* PG3DSetCamera for more details.
-
-* Parameters:
-* eye
-* The position vector of the camera's "eye", in 3D world coordinates.
-* Zero is returned if the new eye position is the same as the
-* existing camera target position.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-* - This function can only be called to modify an existing Camera.
-* Consequently it returns zero if a camera has not already been set
-* for the current PGPLOT device by calling PG3DSetCamera.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
-
-/* If so, modify the camera values, using the supplied eye position but
- retaining the other camera settings. */
- result = PG3DSetCamera( eye, cam->target_vector, cam->up_vector,
- cam->screen_distance );
- }
-
- return result;
-}
-
-int PG3DRotateEye( int dir, float angle ){
-/*
-*+
-* Name:
-* PG3DRotateEye
-
-* Purpose:
-* Move the eye on a great circle around the current target position.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DRotateEye( int dir, float angle )
-
-* Description:
-* This function modifies the camera eye position for the current
-* PGPLOT device. Other camera settings are left unchanged. See
-* PG3DSetCamera for more details.
-*
-* The eye is moved by a gven distance along an arc of a great circle
-* centred on the current target position. The target position itself
-* is left unchanged.
-
-* Parameters:
-* dir
-* The direction in which to move the eye position:
-* 1 - Move eye upwards
-* 2 - Move eye downwards
-* 3 - Move eye left
-* 4 - Move eye right
-* angle
-* The arc-distance, in degrees, by which to move the eye.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-* - This function can only be called to modify an existing Camera.
-* Consequently it returns zero if a camera has not already been set
-* for the current PGPLOT device by calling PG3DSetCamera.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
- int i;
- float e[3], f[3], emod, neweye[3], sina, cosa;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
-
-/* Get the cos and sine of the supplied angle. */
- cosa = cos( angle*TWOPI/360 );
- sina = sin( angle*TWOPI/360 );
-
-/* Get the vector from the target to the eye, get its modulus. */
- vectorSub( cam->eye_vector, cam->target_vector, e );
- emod = vectorModulus( e );
-
-/* If we are moving the eye upwards, find the new eye position. */
- if( dir == 1 ) {
- for( i = 0; i < 3; i++ ) {
- neweye[ i ] = e[ i ]*cosa + emod*cam->up_vector[ i ]*sina +
- cam->target_vector[ i ];
- }
-
-/* If we are moving the eye downwards, find the new eye position. */
- } else if( dir == 2 ) {
- for( i = 0; i < 3; i++ ) {
- neweye[ i ] = e[ i ]*cosa - emod*cam->up_vector[ i ]*sina +
- cam->target_vector[ i ];
- }
-
-/* If we are moving the eye left or right we need a vector in the plane
- of rotation that is at right angles to "e", and points to the right
- of the eye. */
- } else {
- vectorProduct( cam->up_vector, e, f );
- vectorNorm( f );
-
-/* Get the new eye position. */
- if( dir == 3 ) {
- for( i = 0; i < 3; i++ ) {
- neweye[ i ] = e[ i ]*cosa - emod*f[ i ]*sina + cam->target_vector[ i ];
- }
-
- } else {
- for( i = 0; i < 3; i++ ) {
- neweye[ i ] = e[ i ]*cosa + emod*f[ i ]*sina + cam->target_vector[ i ];
- }
- }
- }
-
-/* Modify the camera eye vector, retaining the other camera settings. */
- result = PG3DSetCamera( neweye, cam->target_vector, cam->up_vector,
- cam->screen_distance );
- }
-
- return result;
-}
-
-int PG3DRotateTarget( int axis, float angle ){
-/*
-*+
-* Name:
-* PG3DRotateTarget
-
-* Purpose:
-* Move the target by rotating the (u,v,w) coordinate system.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DRotateTarget( int dir, float angle )
-
-* Description:
-* This function modifies the camera target position for the current
-* PGPLOT device. Other camera settings are left unchanged. See
-* PG3DSetCamera for more details.
-*
-* The (u,v,w) coordinate system that defines the position of the
-* target relative to the eye is rotated, and the target is placed at
-* the end of the "w" axis. The eye position is left unchanged. This
-* is equivalent to a roll, pitch or yaw of the camera.
-
-* Parameters:
-* axis
-* The axis around which to rotate:
-* 1 - the U axis (pitch)
-* 2 - the V axis (yaw)
-* 3 - the W axis (roll)
-* angle
-* The angle, in degrees, by which to rotate around the specified
-* axis.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-* - This function can only be called to modify an existing Camera.
-* Consequently it returns zero if a camera has not already been set
-* for the current PGPLOT device by calling PG3DSetCamera.
-*-
-*/
-
-/* Local Variables: */
- float m[ 9 ], newmat[ 9 ];
- Camera *cam;
- int result = 0;
- int i, j, k;
- float sina, cosa, *p, *p1, *p2;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
- result = 1;
-
-/* Get the cos and sine of the supplied angle. */
- cosa = cos( angle*TWOPI/360 );
- sina = sin( angle*TWOPI/360 );
-
-/* Get the 3x3 rotation matrix. */
- if( axis == 1 ) {
- m[ 0 ] = 1.0;
- m[ 1 ] = 0.0;
- m[ 2 ] = 0.0;
- m[ 3 ] = 0.0;
- m[ 4 ] = cosa;
- m[ 5 ] = -sina;
- m[ 6 ] = 0.0;
- m[ 7 ] = sina;
- m[ 8 ] = cosa;
-
- } else if( axis == 2 ) {
- m[ 0 ] = cosa;
- m[ 1 ] = 0.0;
- m[ 2 ] = -sina;
- m[ 3 ] = 0.0;
- m[ 4 ] = 1.0;
- m[ 5 ] = 0.0;
- m[ 6 ] = sina;
- m[ 7 ] = 0.0;
- m[ 8 ] = cosa;
-
- } else if( axis == 3 ) {
- m[ 0 ] = cosa;
- m[ 1 ] = -sina;
- m[ 2 ] = 0.0;
- m[ 3 ] = sina;
- m[ 4 ] = cosa;
- m[ 5 ] = 0.0;
- m[ 6 ] = 0.0;
- m[ 7 ] = 0.0;
- m[ 8 ] = 1.0;
-
- } else {
- result = 0;
- }
-
-/* If the axis value is OK, multiple the existing w2c_matrix by the
- rotation matrix to get the new camera matrix. The w2c_matrix is a
- 3x3 matrix that rotates vectors in the (x,y,z) system into vectors
- in the (u,v,w) system. Each row in the matrix is a unit vector
- along the u, v or w axes. */
- p = newmat;
- for( i = 0; i < 3; i++ ) {
- for( j = 0; j < 3; j++, p++ ) {
- p1 = m + i*3;
- p2 = cam->w2c_matrix + j;
- *p = 0.0;
- for( k = 0; k < 3; k++ ) {
- *p += (*p1) * (*p2);
- p1++;
- p2 += 3;
- }
- }
- }
-
-/* Store the new camera matrix. */
- memcpy( cam->w2c_matrix, newmat, sizeof(float)*9 );
-
-/* Store corresponding new values for the target and up vectors. */
- for( k = 0; k < 3; k++ ) {
- cam->target_vector[ k ] = cam->eye_vector[ k ] +
- newmat[ 6 + k ]*cam->screen_distance;
- }
- memcpy( cam->up_vector, newmat + 3, 3*sizeof( float ) );
-
- }
-
- return result;
-}
-
-int PG3DForward( float distance ){
-/*
-*+
-* Name:
-* PG3DForward
-
-* Purpose:
-* Move the eye forward towards the target.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DForward( float distance )
-
-* Description:
-* This function modifies the camera eye position for the current
-* PGPLOT device. Other camera settings are left unchanged. See
-* PG3DSetCamera for more details.
-*
-* The eye is moved forward by a given distance towards the target
-* point, and the target point is also moved forward so that the
-* distance between eye and target remains unchanged.
-
-* Parameters:
-* distance
-* The distance to move the eye and target, given as a fraction of
-* the distance between the eye and the target.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-* - This function can only be called to modify an existing Camera.
-* Consequently it returns zero if a camera has not already been set
-* for the current PGPLOT device by calling PG3DSetCamera.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
- int i;
- float e[3], newtarg[3], neweye[3];
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
-
-/* Get the vector from the eye to the target. */
- vectorSub( cam->target_vector, cam->eye_vector, e );
-
-/* Find the new eye and target positions. */
- for( i = 0; i < 3; i++ ){
- neweye[ i ] = cam->eye_vector[ i ] + e[ i ]*distance;
- newtarg[ i ] = cam->target_vector[ i ] + e[ i ]*distance;
- }
-
-/* Modify the camera eye and target vectors, retaining the other camera
- settings. */
- result = PG3DSetCamera( neweye, newtarg, cam->up_vector,
- cam->screen_distance );
- }
-
- return result;
-}
-
-
-int PG3DFindNearest( int n, float *x, float *y, float *z, int *iclose ){
-/*
-*+
-* Name:
-* PG3DFindNearest
-
-* Purpose:
-* Find the closest point to the eye.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DFindNearest( int n, float *x, float *y, float *z, int *iclose )
-
-* Description:
-* This function checks every supplied point and returns the index of
-* the point that is closest to the eye.
-
-* Parameters:
-* n
-* The number of points to check.
-* x
-* Pointer to an array of "n" X values.
-* y
-* Pointer to an array of "n" Y values.
-* z
-* Pointer to an array of "n" Z values.
-* iclose
-* Pointer to an int in which to return the index of hte nearest
-* point.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
- int i;
- float c[3], v[3];
- float d;
- float dmin;
-
- *iclose = 0;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
- result = 1;
-
-/* Loop through all the supplied positions. */
- dmin = FLT_MAX;
- for( i = 0; i < n; i++ ) {
-
-/* Get the required distance. */
- v[ 0 ] = x[ i ];
- v[ 1 ] = y[ i ];
- v[ 2 ] = z[ i ];
- vectorSub( v, cam->eye_vector, c );
- d = vectorModulus( c );
-
-/* If this is the smallest distance so far, remember it. */
- if( d < dmin ) {
- dmin = d;
- *iclose = i;
- }
- }
- }
-
- return result;
-}
-
-
-int PG3DSetTarget( float target[3] ){
-/*
-*+
-* Name:
-* PG3DSetTarget
-
-* Purpose:
-* Store a new camera target position for the current PGPLOT device.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DSetTarget( float target[3] )
-
-* Description:
-* This function modifies the camera target position for the current
-* PGPLOT device. Other camera settings are left unchanged. See
-* PG3DSetCamera for more details.
-
-* Parameters:
-* target
-* The position vector of the camera's "target", in 3D world coordinates.
-* Zero is returned if the new target position is the same as the
-* existing camera eye position.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-* - This function can only be called to modify an existing Camera.
-* Consequently it returns zero if a camera has not already been set
-* for the current PGPLOT device by calling PG3DSetCamera.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
-
-/* If so, modify the camera values, using the supplied target position but
- retaining the other camera settings. */
- result = PG3DSetCamera( cam->eye_vector, target, cam->up_vector,
- cam->screen_distance );
- }
-
- return result;
-}
-
-
-int PG3DSetUp( float up[3] ){
-/*
-*+
-* Name:
-* PG3DSetUp
-
-* Purpose:
-* Store a new camera up vector for the current PGPLOT device.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DSetUp( float up[3] )
-
-* Description:
-* This function modifies the camera up vector for the current
-* PGPLOT device. Other camera settings are left unchanged. See
-* PG3DSetCamera for more details.
-
-* Parameters:
-* up
-* The new up vector, in 3D world coordinates. Zero is returned if
-* the new up vector is parallel to the line joining the eye and
-* the target positions.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-* - This function can only be called to modify an existing Camera.
-* Consequently it returns zero if a camera has not already been set
-* for the current PGPLOT device by calling PG3DSetCamera.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
-
-/* If so, modify the camera values, using the supplied up vector but
- retaining the other camera settings. */
- result = PG3DSetCamera( cam->eye_vector, cam->target_vector, up,
- cam->screen_distance );
- }
-
- return result;
-}
-
-
-int PG3DSetScreen( float screen ){
-/*
-*+
-* Name:
-* PG3DSetScreen
-
-* Purpose:
-* Store a new camera screen distance for the current PGPLOT device.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DSetScreen( float screen )
-
-* Description:
-* This function modifies the camera screen distance for the current
-* PGPLOT device. Other camera settings are left unchanged. See
-* PG3DSetCamera for more details.
-
-* Parameters:
-* screen
-* The distance from the camera's eye to the projection screen in
-* 3D world coordinate units. If this is zero, then an orthographic
-* projection is used.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-* - This function can only be called to modify an existing Camera.
-* Consequently it returns zero if a camera has not already been set
-* for the current PGPLOT device by calling PG3DSetCamera.
-*-
-*/
-
-/* Local Variables: */
- Camera *cam;
- int result = 0;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 1 );
- if( cam ) {
-
-/* If so, modify the camera values, using the supplied screen distance but
- retaining the other camera settings. */
- result = PG3DSetCamera( cam->eye_vector, cam->target_vector,
- cam->up_vector, screen );
- }
-
- return result;
-}
-
-int PG3DAutoCamera( float lbnd[3], float ubnd[3] ){
-/*
-*+
-* Name:
-* PG3DAutoCamera
-
-* Purpose:
-* Set up a default camera to view a given box of 3D world coords.
-
-* Synopsis:
-* #include "grf3d.h"
-* int PG3DAutoCamera( float lbnd[3], float ubnd[3] )
-
-* Description:
-* This function sets up the camera and the 2D PGPLOT window for the
-* current device so that it produces a default view of a specified
-* volume of 3D world coordinate space.
-
-* Parameters:
-* lbnd
-* The lower bounds of the volume of 3D world coordinates that
-* is to be visible using the camera and 2D PGPLOT window.
-* ubnd
-* The upper bounds of the volume of 3D world coordinates that
-* is to be visible using the camera and 2D PGPLOT window.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - Zero is returned if no PGPLOT device has been opened prior to
-* calling this function.
-*-
-*/
-
-/* Local Variables: */
- float target[3], eye[3], up[3], screen, dx, dy, dz, hlo, hhi, rlo, rhi;
- float x[8], y[8], z[8], h[8], r[8];
- Camera *cam;
- int result = 0;
- int i;
-
-/* Get a pointer to the Camera structure for the current PGPLOT device.
- Return without action if no PGPLOT device is open. */
- cam = getCamera( 0 );
- if( cam ) {
-
-/* The target position (i.e. the position towards which the camera is
- looking) is the middle of the volume. */
- target[ 0 ] = 0.5*( lbnd[ 0 ] + ubnd[ 0 ] );
- target[ 1 ] = 0.5*( lbnd[ 1 ] + ubnd[ 1 ] );
- target[ 2 ] = 0.5*( lbnd[ 2 ] + ubnd[ 2 ] );
-
-/* The eye is slightly offset from a corner view. */
- eye[ 0 ] = 0.85*ubnd[ 0 ] + 0.15*lbnd[ 0 ];
- eye[ 1 ] = 0.75*ubnd[ 1 ] + 0.25*lbnd[ 1 ];
- eye[ 2 ] = 0.75*ubnd[ 2 ] + 0.25*lbnd[ 2 ];
-
-/* The eye is seven times the size of the box away from the box centre. */
- eye[ 0 ] = 7*(eye[ 0 ] - target[ 0 ] ) + target[ 0 ];
- eye[ 1 ] = 7*(eye[ 1 ] - target[ 1 ] ) + target[ 1 ];
- eye[ 2 ] = 7*(eye[ 2 ] - target[ 2 ] ) + target[ 2 ];
-
-/* The up vector is paralle to the Z axis. */
- up[ 0 ] = 0.0;
- up[ 1 ] = 0.0;
- up[ 2 ] = 1.0;
-
-/* The screen is at the centre of the box. */
- dx = eye[ 0 ] - target[ 0 ];
- dy = eye[ 1 ] - target[ 1 ];
- dz = eye[ 2 ] - target[ 2 ];
- screen = sqrtf( dx*dx + dy*dy + dz*dz );
-
-/* Set the camera. */
- if( PG3DSetCamera( eye, target, up, screen ) ) {
-
-/* Get the 3D World coords at the corners of the volume. */
- x[ 0 ] = ubnd[ 0 ];
- x[ 1 ] = ubnd[ 0 ];
- x[ 2 ] = lbnd[ 0 ];
- x[ 3 ] = lbnd[ 0 ];
- x[ 4 ] = ubnd[ 0 ];
- x[ 5 ] = ubnd[ 0 ];
- x[ 6 ] = lbnd[ 0 ];
- x[ 7 ] = lbnd[ 0 ];
-
- y[ 0 ] = lbnd[ 1 ];
- y[ 1 ] = ubnd[ 1 ];
- y[ 2 ] = ubnd[ 1 ];
- y[ 3 ] = lbnd[ 1 ];
- y[ 4 ] = lbnd[ 1 ];
- y[ 5 ] = ubnd[ 1 ];
- y[ 6 ] = ubnd[ 1 ];
- y[ 7 ] = lbnd[ 1 ];
-
- z[ 0 ] = lbnd[ 2 ];
- z[ 1 ] = lbnd[ 2 ];
- z[ 2 ] = lbnd[ 2 ];
- z[ 3 ] = lbnd[ 2 ];
- z[ 4 ] = ubnd[ 2 ];
- z[ 5 ] = ubnd[ 2 ];
- z[ 6 ] = ubnd[ 2 ];
- z[ 7 ] = ubnd[ 2 ];
-
-/* Transform these into screen coordinates. */
- if( transform( cam, 8, x, y, z, h, r ) ) {
-
-/* Find the bounds in h and r of the projection of the volume. */
- hlo = FLT_MAX;
- hhi = -FLT_MAX;
- rlo = FLT_MAX;
- rhi = -FLT_MAX;
-
- for( i = 0; i < 8; i++ ) {
- if( h[ i ] < hlo ) hlo = h[ i ];
- if( h[ i ] > hhi ) hhi = h[ i ];
- if( r[ i ] < rlo ) rlo = r[ i ];
- if( r[ i ] > rhi ) rhi = r[ i ];
- }
-
-/* Extend these bounds by 5% at each end */
- dx = 0.05*( hhi - hlo );
- hhi += dx;
- hlo -= dx;
-
- dy = 0.05*( rhi - rlo );
- rhi += dy;
- rlo -= dy;
-
-/* If the box has non-zero area, set it as the 2D PGPLOT window, and
- indicate success. */
- if( rlo < rhi && hlo < hhi ) {
- ccpgswin( hlo, hhi, rlo, rhi );
- result = 1;
- }
- }
- }
- }
- return result;
-}
-
-
-
-
-
-/* Private functions for this module */
-/* ================================= */
-
-static int TextCam( Camera *textcam, float ref[3], float tx[3], float ty[3],
- float tz[3] ){
-/*
-* Name:
-* TextCam
-
-* Purpose:
-* Create a Camera that converts 3D text plane coordinates into 2D world
-* coordinates.
-
-* Synopsis:
-* #include "grf3d.h"
-* int TextCam( Camera *textcam, float ref[3], float tx[3], float ty[3],
-* float tz[3] )
-
-* Description:
-* This function initialises the contents of a supplied Camera
-* structure so that the Camera describes the transformation from 3D
-* "text plane" coordinates to 2D PGPLOT world coordinates. The text
-* plane coordinate system is defined by three vectors along its x, y
-* and z axes, and an origin position.
-*
-* Text plane coordinates describe a plane upon which 2D graphics such
-* as text is drawn. The X axis is parallel to the text base line, the
-* Y axis is the text up vector, and the Z axis is perpendicular to
-* the text, passing from the back of the text to the front of the text.
-
-* Parameters:
-* textcam
-* The Camera structure which is to be modified.
-* ref
-* The (x,y,z) coordinates at the text plane origin.
-* tx
-* A unit vector (expressed in 3D world coords) along the text plane
-* X axis. This is parallel to the text base line.
-* ty
-* A unit vector (expressed in 3D world coords) along the text plane
-* Y axis. This is parallel to the projectionof ht eup vector on to
-* the text plane.
-* tz
-* A unit vector (expressed in 3D world coords) along the text plane
-* Z axis. This is perpendicular to the text plane, passing from
-* the back of the text to the front of the text.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-*/
-
-
-/* Local Variables: */
- Camera *cam;
- float dx, dy, dz;
- int i;
- float a, b, c;
-
-/* Get the Camera for the current device identifier. Abort if no camera
- is available. This camera describes the transformation from 3D world
- coordinates (x,y,z) to 2D world coordinates (screen coordinates) (h,r). */
- cam = getCamera( 1 );
- if( !cam ) return 0;
-
-/* Create a Camera structure that describes the transformation from
- text plane coordinates to 2D world coords, putting the origin of text
- plane coordinates at the given reference position. */
- dx = cam->eye_vector[ 0 ] - ref[ 0 ];
- dy = cam->eye_vector[ 1 ] - ref[ 1 ];
- dz = cam->eye_vector[ 2 ] - ref[ 2 ];
-
- textcam->eye_vector[ 0 ] = tx[ 0 ]*dx + tx[ 1 ]*dy + tx[ 2 ]*dz;
- textcam->eye_vector[ 1 ] = ty[ 0 ]*dx + ty[ 1 ]*dy + ty[ 2 ]*dz;
- textcam->eye_vector[ 2 ] = tz[ 0 ]*dx + tz[ 1 ]*dy + tz[ 2 ]*dz;
-
- for( i = 0; i < 8; i += 3 ) {
- a = cam->w2c_matrix[ i ];
- b = cam->w2c_matrix[ i + 1 ];
- c = cam->w2c_matrix[ i + 2 ];
- textcam->w2c_matrix[ i ] = a*tx[ 0 ] + b*tx[ 1 ] + c*tx[ 2 ];
- textcam->w2c_matrix[ i + 1 ] = a*ty[ 0 ] + b*ty[ 1 ] + c*ty[ 2 ];
- textcam->w2c_matrix[ i + 2 ] = a*tz[ 0 ] + b*tz[ 1 ] + c*tz[ 2 ];
- }
-
- textcam->screen_distance = cam->screen_distance;
- textcam->ok_flag = CAMERA_OK;
-
- return 1;
-}
-
-static int Polygon( int nside, float *vx, float *vy, float *vz, float ref[3],
- float tx[3], float ty[3], float tz[3] ){
-/*
-* Name:
-* Polygon
-
-* Purpose:
-* Draw a regular polygon.
-
-* Synopsis:
-* #include "grf3d.h"
-* int Polygon( int nside, float *vx, float *vy, float *vz, float ref[3],
-* float tx[3], float ty[3], float tz[3] )
-
-* Description:
-* This function draws a polygon centred at a given position on a
-* given plane in 3D world coords, using a specified up-vector. The
-* polygon vertices are specified in text plane coordinates via vx,
-* vy and vz.
-
-* Parameters:
-* nside
-* Number of sides for the polygon. Numbers higher than 32 are
-* treated as 32.
-* vx
-* Pointer to an array of "nside" text plane X axis values.
-* vy
-* Pointer to an array of "nside" text plane Y axis values.
-* vz
-* Pointer to an array of "nside" text plane Z axis values.
-* ref
-* The (x,y,z) coordinates at the polygon centre.
-* tx
-* A unit vector (expressed in 3D world coords) along the text plane
-* X axis. This is parallel to the text base line.
-* ty
-* A unit vector (expressed in 3D world coords) along the text plane
-* Y axis. This is parallel to the projectionof ht eup vector on to
-* the text plane.
-* tz
-* A unit vector (expressed in 3D world coords) along the text plane
-* Z axis. This is perpendicular to the text plane, passing from
-* the back of the text to the front of the text.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-*/
-
-
-/* Local Variables: */
- Camera *cam;
- Camera newcam;
- float h[ MXSIDE ], r[ MXSIDE ];
-
-/* Get the Camera for the current device identifier. Abort if no camera
- is available. */
- cam = getCamera( 1 );
- if( !cam ) return 0;
-
-/* Check the number of points. */
- if( nside > MXSIDE) return 0;
-
-/* Create a Camera structure that describes the transformation from
- text plane coordinates to 2D world coords, putting the origin of text
- plane coordinates at the given reference position. */
- if( !TextCam( &newcam, ref, tx, ty, tz ) ) return 0;
-
-/* Transform the given text plane coordinates into 2D world coordinates. */
- if( !transform( &newcam, nside, vx, vy, vz, h, r ) ) return 0;
-
-/* Draw the polygon. */
- ccpgpoly( nside, h, r );
-
-/* If we get here we have succeeded so return a non-zero value. */
- return 1;
-}
-
-static int Text( int *list, int nlist, float ref[3], const char *just,
- float tx[3], float ty[3], float tz[3] ){
-/*
-* Name:
-* Text
-
-* Purpose:
-* Draw a character string.
-
-* Synopsis:
-* #include "grf3d.h"
-* int Text( int *list, int nlist, float ref[3], const char *just,
-* float tx[3], float ty[3], float tz[3] )
-
-* Description:
-* This function displays a symbol list at a given position on a given
-* plane in 3D world coords, using a specified justification and up-vector.
-
-* Parameters:
-* list
-* Pointer to an array of pgplot symbol values.
-* nlist
-* Length of the "list" array.
-* ref
-* The reference (x,y,z) coordinates.
-* just
-* A character string which specifies the location within the
-* text string which is to be placed at the reference position
-* given by x and y. The first character may be 'T' for "top",
-* 'C' for "centre", or 'B' for "bottom", and specifies the
-* vertical location of the reference position. Note, "bottom"
-* corresponds to the base-line of normal text. Some characters
-* (eg "y", "g", "p", etc) descend below the base-line. The second
-* character may be 'L' for "left", 'C' for "centre", or 'R'
-* for "right", and specifies the horizontal location of the
-* reference position. If the string has less than 2 characters
-* then 'C' is used for the missing characters.
-* tx
-* A unit vector (expressed in 3D world coords) along the text plane
-* X axis. This is parallel to the text base line.
-* ty
-* A unit vector (expressed in 3D world coords) along the text plane
-* Y axis. This is parallel to the projection of the up vector on to
-* the text plane.
-* tz
-* A unit vector (expressed in 3D world coords) along the text plane
-* Z axis. This is perpendicular to the text plane, passing from
-* the back of the text to the front of the text.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - This routine does not recognise PGPLOT escape sequences.
-* - A NULL value for "just" causes a value of "CC" to be used.
-*/
-
-/* Local Constants: */
-#define MXLEN 256
-
-/* Local Variables: */
- Camera *cam;
- Camera newcam;
- float ch;
- float tm, txc, tyc;
- float txleft, tybase;
- float xt[ 150 ], yt[ 150 ], zt[ 150 ], h[ 150 ], r[ 150 ];
- float xb[3], yb[3], zb[3], bl[3];
- int clip;
- int i;
- int j;
- int k;
- int unused;
- int xygrid[ 300 ];
-
-/* If there is nothing to plot return without error. */
- if( nlist == 0 ) return 1;
-
-/* Find the 3D world coordinates at the left hand end of the text
- baseline. */
- if( !TxExt( list, nlist, ref, just, tx, ty, tz, xb, yb, zb, bl ) ) return 0;
-
-/* Get the Camera for the current device identifier. Abort if no camera
- is available. */
- if( ! (cam = getCamera( 1 ) ) ) return 0;
-
-/* Create a Camera structure that describes the transformation from
- text plane coordinates to 2D world coords. */
- if( !TextCam( &newcam, ref, tx, ty, tz ) ) return 0;
-
-/* Save the current clipping flag, and ensure clipping is off. */
- ccpgqclp( &clip );
- ccpgsclp( 0 );
-
-/* Calculate the text plane X coord of the left hand edge of the first
- character. */
- txleft = tx[ 0 ]*( bl[ 0 ] - ref[ 0 ] ) +
- tx[ 1 ]*( bl[ 1 ] - ref[ 1 ] ) +
- tx[ 2 ]*( bl[ 2 ] - ref[ 2 ] );
-
-/* Calculate the text plane Y coord at the text baseline. */
- tybase = ty[ 0 ]*( bl[ 0 ] - ref[ 0 ] ) +
- ty[ 1 ]*( bl[ 1 ] - ref[ 1 ] ) +
- ty[ 2 ]*( bl[ 2 ] - ref[ 2 ] );
-
-/* Get the character height in world coordinate units. A PGPLOT
- character height of 1.0 corresponds to 1/40 of the 2D window height. */
- ch = getCharHeight();
-
-/* Get the polylines that correspond to the first symbol. */
- ccgrsyxd( list[ 0 ], xygrid, &unused );
-
-/* Create a linear transformation that maps the font grid coordinate
- system used by grsyxd onto text plane coordinates. This transformation
- will be different for each character in the string. The initial
- transformation set up now is appropriate for the first character. The
- mapping is:
-
- Text_x = txc + tm*Font_x
- Text_y = tyc + tm*Font_y
-
-*/
- tm = ch/( xygrid[ 2 ] - xygrid[ 1 ] );
- tyc = tybase - tm*xygrid[ 1 ];
- txc = txleft - tm*xygrid[ 3 ];
-
-/* Loop round each symbol. */
- for( i = 0; i < nlist; i++ ) {
-
-/* Loop round each polyline that forms a segment of the character */
- k = 5;
- while( 1 ) {
-
-/* Map the polyline vertices into text plane coordinates. */
- j = 0;
- while( j < 150 ){
- if( xygrid[ k ] != -64 ) {
- xt[ j ] = txc + tm*xygrid[ k++ ];
- yt[ j ] = tyc + tm*xygrid[ k++ ];
- zt[ j++ ] = 0.0;
- } else {
- break;
- }
- }
-
-/* Map the text plane coordinates into 2D world coordinates. */
- if( j > 0 ) {
- (void) transform( &newcam, j, xt, yt, zt, h, r );
-
-/* Draw the polyline. */
- ccpgline( j, h, r );
- }
-
-/* If this is the last segment in the character, pass on to the next
- character. */
- if( xygrid[ k + 1 ] == -64 ) break;
-
-/* Otherwise, skip over the end markers in the xygrid array, and go on to
- plot the next polyline segment. */
- k += 2;
- }
-
-/* If this is not the last symbol... */
- if( i != nlist - 1 ) {
-
-/* Set the text x value at which to place the left edge of the next
- character. This is the right hand edge of the character just drawn. */
- txleft += tm*( xygrid[ 4 ] - xygrid[ 3 ] );
-
-/* Get the polylines that correspond to the next symbol. */
- ccgrsyxd( list[ i + 1 ], xygrid, &unused );
-
-/* Modify the transformation from font grid coords to text plane coords
- so that it is appropriate for the next character in the string. */
- txc = txleft - tm*xygrid[ 3 ];
- }
-
-/* Next symbol. */
- }
-
-/* Re-instate original clipping flag. */
- ccpgsclp( clip );
-
-/* If we arrive here, we have been successful, so return a non-zero
- value. */
- return 1;
-
-/* Clear local constants. */
-#undef MXLEN
-}
-
-static int TxExt( int *list, int nlist, float ref[3], const char *just,
- float tx[3], float ty[3], float tz[3], float *xb, float *yb,
- float *zb, float bl[3] ){
-/*
-* Name:
-* TxExt
-
-* Purpose:
-* Get the extent of a character string.
-
-* Synopsis:
-* #include "grf3d.h"
-* int TxExt( int *list, int nlist, float ref[3], const char *just,
-* float tx[3], float ty[3], float tz[3], float *xb, float *yb,
-* float *zb, float bl[3] )
-
-* Description:
-* This function returns the corners of a box which would enclose the
-* supplied symbol list if it were displayed using Text.
-*
-* The returned box includes any leading or trailing spaces.
-
-* Parameters:
-* list
-* Pointer to an array of pgplot symbol numbers.
-* nlist
-* The length of the "list" array.
-* ref
-* The reference (x,y,z) coordinates.
-* just
-* A character string which specifies the location within the
-* text string which is to be placed at the reference position
-* given by x and y. The first character may be 'T' for "top",
-* 'C' for "centre", 'B' for "baseline", or "M" for "bottom", and
-* specifies the vertical location of the reference position. Note,
-* "baseline" corresponds to the base-line of normal text. Some
-* characters (eg "y", "g", "p", etc) descend below the base-line,
-* and so "M" and "B" will produce different effects for such
-* characters. The second character may be 'L' for "left", 'C' for
-* "centre", or 'R' for "right", and specifies the horizontal
-* location of the reference position. If the string has less than
-* 2 characters then 'C' is used for the missing characters.
-* tx
-* A unit vector (expressed in 3D world coords) along the text plane
-* X axis. This is parallel to the text base line.
-* ty
-* A unit vector (expressed in 3D world coords) along the text plane
-* Y axis. This is parallel to the projectionof ht eup vector on to
-* the text plane.
-* tz
-* A unit vector (expressed in 3D world coords) along the text plane
-* Z axis. This is perpendicular to the text plane, passing from
-* the back of the text to the front of the text.
-* xb
-* An array of 4 elements in which to return the x coordinate of
-* each corner of the bounding box.
-* yb
-* An array of 4 elements in which to return the y coordinate of
-* each corner of the bounding box.
-* zb
-* An array of 4 elements in which to return the z coordinate of
-* each corner of the bounding box.
-* bl
-* The 3D world coordinates at the left hand end of the text
-* baseline.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-
-* Notes:
-* - The order of the corners is anti-clockwise starting at the
-* bottom left when viewing the text normally (i.e. face on).
-* - This routine does not recognise PGPLOT escape sequences.
-* - A NULL value for "just" causes a value of "CC" to be used.
-*/
-
-/* Local Constants: */
-#define MXLEN 256
-
-/* Local Variables: */
- float ch;
- float txlo, txhi, tylo, tyhi, tyzero;
- float tm;
- float w;
- int i;
- int unused;
- int xygrid[ 300 ];
- int gylo, gyhi, width;
-
-/* Initialise the returned values to indicate no box available. */
- for( i = 0; i < 4; i++ ){
- xb[ i ] = 0.0;
- yb[ i ] = 0.0;
- zb[ i ] = 0.0;
- }
-
-/* If there is nothing to plot return without error. */
- if( nlist == 0 ) return 1;
-
-/* We now find the bounding box of the text in "text plane coordinates".
- These are (tx,ty,tz) axes that span the plane upon which the text is
- writtens. The origin of (tx,ty,tz) is at the supplied 3D reference
- position, the X axis increases along the text baseline, and Y axis
- increases along the text up vector, and Z increases from the back
- of the text to the front of the text (all are measured in 3D world
- coord units). We first find the bounds of the text in these text plane
- coordinates, assuming that the bottom left of the text baseline is
- placed at the given reference position (i.e. at the origiin of text
- plane coordinates). */
-
-/* Get the character height in world coordinate units. A PGPLOT
- character height of 1.0 corresponds to 1/40 of the 2D window height. */
- ch = getCharHeight();
-
-/* Initialise the Y bounds of the text bounding box in grid coords. */
- gylo = INT_MAX;
- gyhi = -INT_MAX;
-
-/* Initialise things. */
- width = 0;
- tm = 1.0;
-
-/* Loop round each symbol. */
- for( i = 0; i < nlist; i++ ) {
-
-/* Get the polylines that correspond to this symbol. */
- ccgrsyxd( list[ i ], xygrid, &unused );
-
-/* If this is the first symbol, set the scaling factor that converts
- grid units to text plane units. */
- if( i == 0 ) tm = ch/( xygrid[ 2 ] - xygrid[ 1 ] );
-
-/* Note the highest and lowest y grid value. */
- w = xygrid[ 2 ] - xygrid[ 1 ];
- if( w > gyhi ) gyhi = w;
-
- w = xygrid[ 0 ] - xygrid[ 1 ];
- if( w < gylo ) gylo = w;
-
-/* Increment the total width of the string in grid units. */
- width += xygrid[ 4 ] - xygrid[ 3 ];
- }
-
-/* Set up the bounding box in text plane coordinates. */
- txlo = 0.0;
- txhi = width*tm;
- tylo = gylo*tm;
- tyhi = gyhi*tm;
- tyzero = 0.0;
-
-/* Adjust the text plane bounding box to take account of the specified
- text justification. The above process implicitly assumed a
- justifiation of "BL". */
- if( !just || just[ 0 ] == 'C' || just[ 0 ] == 0 ){
- w = 0.5*( tyhi + tylo );
- tylo -= w;
- tyhi -= w;
- tyzero -= w;
-
- } else if( just[ 0 ] == 'T' ){
- w = tyhi;
- tylo -= w;
- tyhi -= w;
- tyzero -= w;
-
- } else if( just[ 0 ] == 'M' ){
- w = -tylo;
- tylo += w;
- tyhi += w;
- tyzero += w;
-
- } else if( just[ 0 ] != 'B' ) {
- astError( AST__GRFER, "astG3DTxExt: Justification string '%s' "
- "is invalid.", just );
- return 0;
- }
-
- if( !just || just[ 1 ] == 'C' || just[ 1 ] == 0 ){
- w = 0.5*( txhi + txlo );
- txlo -= w;
- txhi -= w;
-
- } else if( just[ 1 ] == 'R' ){
- w = txhi;
- txlo -= w;
- txhi -= w;
-
- } else if( just[ 1 ] == 'L' ){
- w = txlo;
- txlo -= w;
- txhi -= w;
-
- } else {
- astError( AST__GRFER, "astG3DTxExt: Justification string '%s' "
- "is invalid.", just );
- return 0;
- }
-
-/* Use the supplied text plane axis vectors to transform the corners of
- the text plane bounding box into 3D world coordinates. */
- xb[ 0 ] = tx[ 0 ]*txlo + ty[ 0 ]*tylo + ref[ 0 ];
- yb[ 0 ] = tx[ 1 ]*txlo + ty[ 1 ]*tylo + ref[ 1 ];
- zb[ 0 ] = tx[ 2 ]*txlo + ty[ 2 ]*tylo + ref[ 2 ];
-
- xb[ 1 ] = tx[ 0 ]*txhi + ty[ 0 ]*tylo + ref[ 0 ];
- yb[ 1 ] = tx[ 1 ]*txhi + ty[ 1 ]*tylo + ref[ 1 ];
- zb[ 1 ] = tx[ 2 ]*txhi + ty[ 2 ]*tylo + ref[ 2 ];
-
- xb[ 2 ] = tx[ 0 ]*txhi + ty[ 0 ]*tyhi + ref[ 0 ];
- yb[ 2 ] = tx[ 1 ]*txhi + ty[ 1 ]*tyhi + ref[ 1 ];
- zb[ 2 ] = tx[ 2 ]*txhi + ty[ 2 ]*tyhi + ref[ 2 ];
-
- xb[ 3 ] = tx[ 0 ]*txlo + ty[ 0 ]*tyhi + ref[ 0 ];
- yb[ 3 ] = tx[ 1 ]*txlo + ty[ 1 ]*tyhi + ref[ 1 ];
- zb[ 3 ] = tx[ 2 ]*txlo + ty[ 2 ]*tyhi + ref[ 2 ];
-
-/* Also transform the text plane coordinates at the bottom left of the
- text baseline into 3D world coordinates. */
- bl[ 0 ] = tx[ 0 ]*txlo + ty[ 0 ]*tyzero + ref[ 0 ];
- bl[ 1 ] = tx[ 1 ]*txlo + ty[ 1 ]*tyzero + ref[ 1 ];
- bl[ 2 ] = tx[ 2 ]*txlo + ty[ 2 ]*tyzero + ref[ 2 ];
-
-/* If we get here, we have been succesful, so return a non-zero value. */
- return 1;
-
-/* Clear local constants. */
-#undef MXLEN
-}
-
-static float getCharHeight( void ){
-/*
-* Name:
-* getCharHeight
-
-* Purpose:
-* Get the current text height setting.
-
-* Synopsis:
-* #include "grf3d.h"
-* float getCharHeight( void )
-
-* Description:
-* This function returns the PGPLOT character height, scaled into
-* world coordinate units.
-
-* Returned Value:
-* The character height, in world coordinate units.
-
-*/
-
-/* Local Variables: */
- float wx1, wx2, wy1, wy2;
- float ch;
-
-/* Get the bounds of the PGPLTO 2D window. */
- ccpgqwin( &wx1, &wx2, &wy1, &wy2 );
-
-/* Get the normalised PGPLOT character height. */
- ccpgqch( &ch );
-
-/* A PGPLOT character height of 1.0 corresponds to 1/40 of the 2D window
- height. Scale the normalised character height into world coordinate
- units, and return it. */
- return ch*fabs( wy1 - wy2 )/40.0;
-
-}
-
-static int getTextAxes( float ref[3], float up[3], float norm[3],
- const char *just, float tx[3], float ty[3],
- float tz[3], char newjust[3] ){
-/*
-* Name:
-* getTextAxes
-
-* Purpose:
-* Get unit vectors along the text plane coordinate axes.
-
-* Synopsis:
-* #include "grf3d.h"
-* int getTextAxes( float ref[3], float up[3], float norm[3],
-* const char *just, float tx[3], float ty[3],
-* float tz[3], char newjust[3] )
-
-* Description:
-* This function returns three unit vectors that define the axes of a
-* 3D Cartesian coordinate system known as "text plane coordinates".
-* These axes span the plane upon which text (or other graphics) is to
-* be written. The origin is at the supplied 3D reference position, the
-* X axis increases along the text baseline, and Y axis increases along
-* the text up vector, and Z increases from the back of the text to the
-* front of the text (all are measured in 3D world coord units).
-*
-* The returned vectors are reversed if this will result in text
-* appearing more "normal" (i.e. viewed from the front rather than
-* the back, and viewed upright rather thna upside down). If the
-* vectors are reversed, the justification string is also changed so
-* that the text occupies the requested area on the screen.
-
-* Parameters:
-* ref
-* The reference (x,y,z) coordinates.
-* up
-* The (x,y,z) up-vector for the text. The actual up vector used is
-* the projection of the supplied vector onto the plane specified by
-* "norm".
-* norm
-* The (x,y,z) components of a vector that is normal to the plane
-* containing the text. The given vector passes through the text
-* from the back to the front. If all components of this vector are
-* zero, then a normal vector pointing towards the camera eye is used.
-* just
-* The requested text justification, as supplied to astG3DText.
-* tx
-* A unit vector along the text plane X axis.
-* ty
-* A unit vector along the text plane X axis.
-* tz
-* A unit vector along the text plane X axis.
-* newjust
-* The text justification to use.
-
-* Returned Value:
-* A value of 0 is returned if an error occurs, and 1 is returned
-* otherwise.
-*/
-
-/* Local Variables: */
- Camera *cam;
- float eye[3];
-
-/* Initialise the returned justification to equal the supplied
- justification, supplying defaults if required. . */
- if( just ) {
- strncpy( newjust, just, 2 );
- if( !newjust[ 0 ] ) newjust[ 0 ] = 'C';
- if( !newjust[ 1 ] ) newjust[ 1 ] = 'C';
- newjust[ 2 ] = 0;
- } else {
- strcpy( newjust, "CC" );
- }
-
-/* Get the Camera for the current device identifier. Abort if no camera
- is available. */
- if( !( cam = getCamera( 1 ) ) ) return 0;
-
-/* Calculate the vector from the reference position to the eye, and store
- it in "eye". */
- vectorSub( cam->eye_vector, ref, eye );
-
-/* Create unit vectors along the three axes of the text plane coordinate
- system. These unit vectors are represented in terms of the 3D world
- coordinate axes. The text Z axis is parallel to the supplied "norm"
- vector. */
- tz[ 0 ] = norm[ 0 ];
- tz[ 1 ] = norm[ 1 ];
- tz[ 2 ] = norm[ 2 ];
-
-/* Attempt to normalise the "tz" vector. If it has zero length, use the
- offset from the reference point to the eye. */
- if( ! vectorNorm( tz ) ){
-
-/* Use the "eye" vector calculated above as the text plane Z axis. */
- tz[ 0 ] = eye[ 0 ];
- tz[ 1 ] = eye[ 1 ];
- tz[ 2 ] = eye[ 2 ];
- }
-
-/* Find vectors along the text plane x and y axes. */
- vectorProduct( up, tz, tx );
- vectorProduct( tz, tx, ty );
-
-/* Normalise the three text plane axis vectors. If any vector has zero
- length, abort. */
- if( !vectorNorm( tx ) || !vectorNorm( ty ) || !vectorNorm( tz ) ) return 0;
-
-/* We now reverse text plane vectors if this will help ther text to be
- viewed "normally" on the screen. If the existing vectors cause the
- text to be viewed from the back rather than the front, reverse the tx
- and tz vectors so that he text is viewed from the front. */
- if( dotProduct( tz, eye ) < 0.0 ) {
- tz[ 0 ] = -tz[ 0 ];
- tz[ 1 ] = -tz[ 1 ];
- tz[ 2 ] = -tz[ 2 ];
- tx[ 0 ] = -tx[ 0 ];
- tx[ 1 ] = -tx[ 1 ];
- tx[ 2 ] = -tx[ 2 ];
-
-/* The text will have spun around the up vector (i.e. the ty axis), so
- modify the horizontal justification so that thex text occupies the same
- area on the screen. */
- if( newjust[ 1 ] == 'L' ) {
- newjust[ 1 ] = 'R';
- } else if( newjust[ 1 ] == 'R' ) {
- newjust[ 1 ] = 'L';
- }
- }
-
-/* If the existing vectors cause the text to be viewed upside down, reverse
- the tx and ty vectors so that he text is viewed right way up. */
- if( dotProduct( ty, cam->up_vector ) < 0.0 ) {
- ty[ 0 ] = -ty[ 0 ];
- ty[ 1 ] = -ty[ 1 ];
- ty[ 2 ] = -ty[ 2 ];
- tx[ 0 ] = -tx[ 0 ];
- tx[ 1 ] = -tx[ 1 ];
- tx[ 2 ] = -tx[ 2 ];
-
-/* The text will have spun around the tz vector (i.e. the viewing vector),
- so modify both vertical and horizontal justification so that the text
- occupies the same area on the screen. */
- if( newjust[ 0 ] == 'B' || newjust[ 0 ] == 'M' ) {
- newjust[ 0 ] = 'T';
- } else if( newjust[ 0 ] == 'T' ) {
- newjust[ 0 ] = 'M';
- }
-
- if( newjust[ 1 ] == 'L' ) {
- newjust[ 1 ] = 'R';
- } else if( newjust[ 1 ] == 'R' ) {
- newjust[ 1 ] = 'L';
- }
- }
-
-/* If we arraive here we have been succesful, so return a non-zero value. */
- return 1;
-}
-
-static void getSymbolList( const char *text, int mxlen, int *nlist, int *list ){
-/*
-* Name:
-* getSymbolList
-
-* Purpose:
-* Get the extent of a character string.
-
-* Synopsis:
-* #include "grf3d.h"
-* void getSymbolList( const char *text, int mxlen, int *nlist, int *list )
-
-* Description:
-* This function converts a supplied text string into a list of PGPLOT
-* symbol numbers for the current PGPLOT font.
-
-* Parameters:
-* text
-* Pointer to a null-terminated character string.
-* mxlen
-* The length of the "list" array.
-* nlist
-* Pointer to an integer in which to place the number of symbol
-* values stored in the "list" array. This will be returned equal
-* to zero if there are no non-blank characters in the supplied
-* string. If there is one or more non-blank characters in "text",
-* then the returned list will include any trailing spaces.
-* list
-* Pointer to an array in which to return the symbol numbers. The
-* array should be at least "mxlen" elements long.
-*/
-
-
-/* Local Variables: */
- int font;
- int tlen;
-
-/* Assume we have no symbols. */
- *nlist = 0;
-
-/* Check there is something to plot. */
- if( astChrLen( text ) > 0 ) {
-
-/* Find the length of text that can be displayed. */
- tlen = strlen( text );
- if( tlen > mxlen ) tlen = mxlen;
-
-/* Get the current PGPLOT font. */
- ccpgqcf( &font );
-
-/* Convert the supplied string into a list of symbol numbers */
- ccgrsyds( list, nlist, text, tlen, font );
- }
-}
-
-static Camera *getCamera( int check ){
-/*
-*+
-* Name:
-* getCamera
-
-* Purpose:
-* Return a pointer to the Camera structure for the current PGPLOT
-* device.
-
-* Synopsis:
-* #include "grf3d.h"
-* Camera getCamera( int check )
-
-* Description:
-* This function returns a pointer to a static structure that defines the
-* position and orientation of the camera in 3D world coords. It can
-* be used to transform positions from 3D world coordinates (x,y,z) to
-* 2D screen coordinates (h,r).
-
-* Parameters:
-* check
-* If non-zero, a check will be made that the Camera has been
-* initialised, and NULL will be returned if the Camera has not
-* been initialsied. If "check" is zero, a pointer to the Camera
-* is returned even if it has not been initialised.
-
-* Returned Value:
-* Pointer to the Camera, or NULL if an error occurs.
-*-
-*/
-
-/* Local Variables: */
- int id;
- Camera *cam = NULL;
-
-/* Get the pgplot current device identifier. Return NULL if no device is
- currently open. */
- ccpgqid( &id );
- if( id > 0 && id <= MXDEV ) {
-
-/* Get a pointer to the required Camera structure. */
- cam = cameras + id - 1;
-
-/* If required, check that the structure has been initialised. */
- if( check && cam->ok_flag != CAMERA_OK ) cam = NULL;
- }
-
- return cam;
-}
-
-static int transform( Camera *cam, int n, float *x, float *y, float *z,
- float *h, float *r ){
-/*
-*+
-* Name:
-* transform
-
-* Purpose:
-* Transform positions from 3D world coords to 2D screen cooords.
-
-* Synopsis:
-* #include "grf3d.h"
-* int transform( Camera *cam, int n, float *x, float *y, float *z,
-* float *h, float *r )
-
-* Description:
-* This function transforms a set of positions from 3D world
-* coordinates (x,y,z) to 2D screen coordinates (h,r), using the
-* supplied camera.
-
-* Parameters:
-* cam
-* Pointer to a structure descibing the projection from 3D world
-* coords to 2D screen coords. If NULL, the camera for the current
-* PGPLOT device is used.
-* n
-* The number of positions to transform.
-* x
-* An array of "n" values for the "x" axis of the 3D world
-* coordinate system.
-* y
-* An array of "n" values for the "y" axis of the 3D world
-* coordinate system.
-* z
-* An array of "n" values for the "z" axis of the 3D world
-* coordinate system.
-* h
-* An array to receive the "n" values for the "h" axis of the 2D
-* screen coordinate system.
-* r
-* An array to receive the "n" values for the "r" axis of the 2D
-* screen coordinate system.
-
-* Returned Value:
-* Zero if an error occurs. One otherwise.
-
-*-
-*/
-
-/* Local Variables: */
- float dx, dy, dz, u, v, w, f;
- int i;
- int result = 0;
-
-/* If no camera was supplied use the camera for the current PGPLOT
- device. */
- if( ! cam ) cam = getCamera( 0 );
-
-/* Check we now have a usable camera */
- if( cam && cam->ok_flag == CAMERA_OK ) {
- result = 1;
-
-/* Loop round each position. */
- for( i = 0; i < n; i++ ) {
-
-/* Offset from supplied position to the camera eye. */
- dx = x[ i ] - (cam->eye_vector)[ 0 ];
- dy = y[ i ] - (cam->eye_vector)[ 1 ];
- dz = z[ i ] - (cam->eye_vector)[ 2 ];
-
-/* Get the representation of this vector in the (u,v,w) system. */
- u = (cam->w2c_matrix)[ 0 ]*dx +
- (cam->w2c_matrix)[ 1 ]*dy +
- (cam->w2c_matrix)[ 2 ]*dz;
-
- v = (cam->w2c_matrix)[ 3 ]*dx +
- (cam->w2c_matrix)[ 4 ]*dy +
- (cam->w2c_matrix)[ 5 ]*dz;
-
- w = (cam->w2c_matrix)[ 6 ]*dx +
- (cam->w2c_matrix)[ 7 ]*dy +
- (cam->w2c_matrix)[ 8 ]*dz;
-
-/* Find the screen coords, using either a tangent plane or an
- orothograhic projection. */
- if( cam->screen_distance != 0.0 ) {
- if( w != 0.0 ) {
- f = cam->screen_distance/w;
- h[ i ] = -f*u;
- r[ i ] = f*v;
- } else {
- h[ i ] = FLT_MAX;
- r[ i ] = FLT_MAX;
- }
- } else {
- h[ i ] = -u;
- r[ i ] = v;
- }
-
- }
- }
- return result;
-}
-
-
-/* Dot product of a pair of 3-vectors "a" and "b". */
-static float dotProduct( float *a, float *b ){
- return a[ 0 ]*b[ 0 ] + a[ 1 ]*b[ 1 ] + a[ 2 ]*b[ 2 ];
-}
-
-/* Vector product of a pair of 3-vectors "a" and "b". */
-static void vectorProduct( float *a, float *b, float *c ){
- c[ 0 ] = a[ 1 ]*b[ 2 ] - a[ 2 ]*b[ 1 ];
- c[ 1 ] = a[ 2 ]*b[ 0 ] - a[ 0 ]*b[ 2 ];
- c[ 2 ] = a[ 0 ]*b[ 1 ] - a[ 1 ]*b[ 0 ];
-}
-
-/* Vector from "b" to "a" (i.e. a minus b) . */
-static void vectorSub( float *a, float *b, float *c ){
- c[ 0 ] = a[ 0 ] - b[ 0 ];
- c[ 1 ] = a[ 1 ] - b[ 1 ];
- c[ 2 ] = a[ 2 ] - b[ 2 ];
-}
-
-/* Normalises a vector to a unit length. Returns zero if the vector has
- zero length, and 1 otherwise. */
-static int vectorNorm( float *a ){
- float d;
- d = vectorModulus( a );
- if( d > 0.0 ) {
- a[ 0 ] /= d;
- a[ 1 ] /= d;
- a[ 2 ] /= d;
- return 1;
- } else {
- return 0;
- }
-}
-
-/* Return the length of a vector. */
-static float vectorModulus( float *a ){
- return sqrtf( a[ 0 ]*a[ 0 ] + a[ 1 ]*a[ 1 ] + a[ 2 ]*a[ 2 ] );
-}
-
-
-
-
-
-
-
-/* PGPLOT interface functions */
-/* ========================== */
-static void ccpgqclp(int *clip){
- F77_INTEGER_TYPE CLIP;
- F77_CALL(pgqclp)( INTEGER_ARG(&CLIP) );
- *clip = (int) CLIP;
-}
-
-static void ccpgsclp(int clip){
- F77_INTEGER_TYPE CLIP;
- CLIP = (F77_INTEGER_TYPE) clip;
- F77_CALL(pgsclp)( INTEGER_ARG(&CLIP) );
-}
-
-static void ccpgqid(int *id){
- F77_INTEGER_TYPE ID;
- F77_CALL(pgqid)( INTEGER_ARG(&ID) );
- *id = (int) ID;
-}
-
-
-static void ccpgswin(float x1, float x2, float y1, float y2){
- F77_REAL_TYPE X1;
- F77_REAL_TYPE X2;
- F77_REAL_TYPE Y1;
- F77_REAL_TYPE Y2;
-
- X1 = x1;
- X2 = x2;
- Y1 = y1;
- Y2 = y2;
-
- F77_CALL(pgswin)( REAL_ARG(&X1), REAL_ARG(&X2), REAL_ARG(&Y1),
- REAL_ARG(&Y2) );
-}
-
-static void ccpgline(int n, float xpts[], float ypts[] ){
- F77_INTEGER_TYPE N;
- F77_REAL_TYPE *XX;
- F77_REAL_TYPE *YY;
- int i;
-
- XX = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n );
- YY = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n );
-
- if( astOK ){
-
- for( i = 0; i < n; i++ ){
- XX[ i ] = (F77_REAL_TYPE) xpts[ i ];
- YY[ i ] = (F77_REAL_TYPE) ypts[ i ];
- }
-
- N = (F77_INTEGER_TYPE) n;
-
- F77_CALL(pgline)( INTEGER_ARG(&N), REAL_ARRAY_ARG(XX),
- REAL_ARRAY_ARG(YY) );
-
- XX = (F77_REAL_TYPE *) astFree( (void *) XX );
- YY = (F77_REAL_TYPE *) astFree( (void *) YY );
- }
-}
-
-static void ccpgpoly(int n, float xpts[], float ypts[] ){
- F77_INTEGER_TYPE N;
- F77_REAL_TYPE *XX;
- F77_REAL_TYPE *YY;
- int i;
-
- XX = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n );
- YY = (F77_REAL_TYPE *) astMalloc( sizeof( F77_REAL_TYPE )*(size_t) n );
-
- if( astOK ){
-
- for( i = 0; i < n; i++ ){
- XX[ i ] = (F77_REAL_TYPE) xpts[ i ];
- YY[ i ] = (F77_REAL_TYPE) ypts[ i ];
- }
-
- N = (F77_INTEGER_TYPE) n;
-
- F77_CALL(pgpoly)( INTEGER_ARG(&N), REAL_ARRAY_ARG(XX),
- REAL_ARRAY_ARG(YY) );
-
- XX = (F77_REAL_TYPE *) astFree( (void *) XX );
- YY = (F77_REAL_TYPE *) astFree( (void *) YY );
- }
-}
-
-static void ccpgqwin(float *x1, float *x2, float *y1, float *y2){
- F77_REAL_TYPE X1;
- F77_REAL_TYPE X2;
- F77_REAL_TYPE Y1;
- F77_REAL_TYPE Y2;
-
- F77_CALL(pgqwin)( REAL_ARG(&X1), REAL_ARG(&X2), REAL_ARG(&Y1),
- REAL_ARG(&Y2) );
- *x1 = (float) X1;
- *x2 = (float) X2;
- *y1 = (float) Y1;
- *y2 = (float) Y2;
-}
-
-static void ccpgqch(float *ch){
- F77_REAL_TYPE CH;
- F77_CALL(pgqch)( REAL_ARG(&CH) );
- *ch = (float) CH;
-}
-
-static void ccpgqcf(int *cf){
- F77_INTEGER_TYPE CF;
- F77_CALL(pgqcf)( INTEGER_ARG(&CF) );
- *cf = (int) CF;
-}
-
-static void ccgrsyds( int *list, int *nlist, const char *text, int tlen,
- int font ){
- F77_INTEGER_TYPE *LIST;
- F77_INTEGER_TYPE NLIST;
- DECLARE_CHARACTER(LTEXT,MXSTRLEN);
- F77_INTEGER_TYPE FONT;
- int ftext_length;
- int i;
-
- ftext_length = tlen;
- if( ftext_length > LTEXT_length ) ftext_length = LTEXT_length;
- astStringExport( text, LTEXT, ftext_length );
-
- LIST = (F77_INTEGER_TYPE *) astMalloc( sizeof( F77_INTEGER_TYPE )*(size_t) ftext_length );
-
- if( astOK ){
-
- FONT = (F77_INTEGER_TYPE) font;
-
- F77_CALL(grsyds)( INTEGER_ARRAY_ARG(LIST), INTEGER_ARG(&NLIST),
- CHARACTER_ARG(LTEXT), INTEGER_ARG(&FONT)
- TRAIL_ARG(ftext) );
-
- *nlist = (int) NLIST;
- for( i = 0; i < ftext_length; i++ ){
- list[ i ] = (int) LIST[ i ];
- }
-
- LIST = (F77_INTEGER_TYPE *) astFree( (void *) LIST );
- }
-}
-
-static void ccgrsymk( int type, int font, int *symbol ){
- F77_INTEGER_TYPE TYPE;
- F77_INTEGER_TYPE FONT;
- F77_INTEGER_TYPE SYMBOL;
-
- TYPE = (F77_INTEGER_TYPE) type;
- FONT = (F77_INTEGER_TYPE) font;
- F77_CALL(grsymk)( INTEGER_ARG(&TYPE), INTEGER_ARG(&FONT),
- INTEGER_ARG(&SYMBOL) );
- *symbol = (int) SYMBOL;
-}
-
-
-static void ccgrsyxd( int symbol, int *xygrid, int *unused ){
- F77_INTEGER_TYPE SYMBOL;
- DECLARE_INTEGER_ARRAY(XYGRID,300);
- F77_LOGICAL_TYPE UNUSED;
- int i;
-
- SYMBOL = (F77_INTEGER_TYPE) symbol;
- F77_CALL(grsyxd)( INTEGER_ARG(&SYMBOL), INTEGER_ARRAY_ARG(XYGRID),
- LOGICAL_ARG(&UNUSED) );
-
- *unused = ( UNUSED == F77_TRUE );
- for( i = 0; i < 5; i++ ) xygrid[ i ] = (int) XYGRID[ i ];
- for( ; i < 300; i++ ){
- xygrid[ i ] = (int) XYGRID[ i ];
- i++;
- if( ( xygrid[ i ] = (int) XYGRID[ i ] ) == -64 ) break;
- }
-}
-
-static void ccpgupdt( void ){
- F77_CALL(pgupdt)();
-}
-
-static void ccpgqci(int *ci){
- F77_INTEGER_TYPE CI;
- F77_CALL(pgqci)( INTEGER_ARG(&CI) );
- *ci = (int) CI;
-}
-
-static void ccpgqls(int *ls){
- F77_INTEGER_TYPE LS;
- F77_CALL(pgqls)( INTEGER_ARG(&LS) );
- *ls = (int) LS;
-}
-
-static void ccpgqlw(int *lw){
- F77_INTEGER_TYPE LW;
- F77_CALL(pgqlw)( INTEGER_ARG(&LW) );
- *lw = (int) LW;
-}
-
-static void ccpgscf(int cf){
- F77_INTEGER_TYPE CF;
- CF = (F77_INTEGER_TYPE) cf;
- F77_CALL(pgscf)( INTEGER_ARG(&CF) );
-}
-
-static void ccpgsch(float ch){
- F77_REAL_TYPE CH;
- CH = (F77_REAL_TYPE) ch;
- F77_CALL(pgsch)( REAL_ARG(&CH) );
-}
-
-static void ccpgsci(int ci){
- F77_INTEGER_TYPE CI;
- CI = (F77_INTEGER_TYPE) ci;
- F77_CALL(pgsci)( INTEGER_ARG(&CI) );
-}
-
-static void ccpgsls(int ls){
- F77_INTEGER_TYPE LS;
- LS = (F77_INTEGER_TYPE) ls;
- F77_CALL(pgsls)( INTEGER_ARG(&LS) );
-}
-
-static void ccpgslw(int lw){
- F77_INTEGER_TYPE LW;
- LW = (F77_INTEGER_TYPE) lw;
- F77_CALL(pgslw)( INTEGER_ARG(&LW) );
-}
-
-static void ccpgqvsz(int units, float *x1, float *x2, float *y1, float *y2){
- F77_INTEGER_TYPE UNITS;
- F77_REAL_TYPE X1;
- F77_REAL_TYPE X2;
- F77_REAL_TYPE Y1;
- F77_REAL_TYPE Y2;
-
- UNITS = (F77_INTEGER_TYPE) units;
- F77_CALL(pgqvsz)( INTEGER_ARG(&UNITS), REAL_ARG(&X1), REAL_ARG(&X2),
- REAL_ARG(&Y1), REAL_ARG(&Y2) );
- *x1 = (float) X1;
- *x2 = (float) X2;
- *y1 = (float) Y1;
- *y2 = (float) Y2;
-}
-
-
-
-/* Fortran interfaces for public functions in this module. */
-/* ======================================================= */
-
-
-F77_LOGICAL_FUNCTION(pg3d_findnearest)( INTEGER(N),
- REAL_ARRAY(X),
- REAL_ARRAY(Y),
- REAL_ARRAY(Z),
- INTEGER(ICLOSE) ){
- GENPTR_INTEGER(N)
- GENPTR_REAL_ARRAY(X)
- GENPTR_REAL_ARRAY(Y)
- GENPTR_REAL_ARRAY(Z)
- GENPTR_INTEGER(ICLOSE)
- return PG3DFindNearest( *N, X, Y, Z, ICLOSE ) ? F77_TRUE : F77_FALSE;
-}
-
-
-
-F77_LOGICAL_FUNCTION(pg3d_setcamera)( REAL_ARRAY(EYE),
- REAL_ARRAY(TARGET),
- REAL_ARRAY(UP),
- REAL(SCREEN) ){
- GENPTR_REAL_ARRAY(EYE)
- GENPTR_REAL_ARRAY(TARGET)
- GENPTR_REAL_ARRAY(UP)
- GENPTR_REAL(SCREEN)
- return PG3DSetCamera( EYE, TARGET, UP, *SCREEN ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(pg3d_getcamera)( REAL_ARRAY(EYE),
- REAL_ARRAY(TARGET),
- REAL_ARRAY(UP),
- REAL(SCREEN) ){
- GENPTR_REAL_ARRAY(EYE)
- GENPTR_REAL_ARRAY(TARGET)
- GENPTR_REAL_ARRAY(UP)
- GENPTR_REAL(SCREEN)
- return PG3DGetCamera( EYE, TARGET, UP, SCREEN ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(pg3d_rotatetarget)( INTEGER(AXIS), REAL(ANGLE) ){
- GENPTR_INTEGER(AXIS)
- GENPTR_REAL(ANGLE)
- return PG3DRotateTarget( *AXIS, *ANGLE ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(pg3d_autocamera)( REAL_ARRAY(LBND),
- REAL_ARRAY(UBND) ){
- GENPTR_REAL_ARRAY(LBND)
- GENPTR_REAL_ARRAY(UBND)
- return PG3DAutoCamera( LBND, UBND ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(pg3d_seteye)( REAL_ARRAY(EYE) ){
- GENPTR_REAL_ARRAY(EYE)
- return PG3DSetEye( EYE ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(pg3d_setup)( REAL_ARRAY(UP) ){
- GENPTR_REAL_ARRAY(UP)
- return PG3DSetUp( UP ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(pg3d_rotateeye)( INTEGER(DIR), REAL(ANGLE) ){
- GENPTR_INTEGER(DIR)
- GENPTR_REAL(ANGLE)
- return PG3DRotateEye( *DIR, *ANGLE ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(pg3d_forward)( REAL(DISTANCE) ){
- GENPTR_REAL(DISTANCE)
- return PG3DForward( *DISTANCE ) ? F77_TRUE : F77_FALSE;
-}
-
-F77_LOGICAL_FUNCTION(ast_g3dmark)( INTEGER(N),
- REAL_ARRAY(X),
- REAL_ARRAY(Y),
- REAL_ARRAY(Z),
- INTEGER(TYPE),
- REAL_ARRAY(NORM)){
- GENPTR_INTEGER(N)
- GENPTR_REAL_ARRAY(X)
- GENPTR_REAL_ARRAY(Y)
- GENPTR_REAL_ARRAY(Z)
- GENPTR_INTEGER(TYPE)
- GENPTR_REAL_ARRAY(NORM)
- return astG3DMark( *N, X, Y, Z, *TYPE, NORM ) ? F77_TRUE : F77_FALSE;
-
-}
-
-F77_LOGICAL_FUNCTION(ast_g3dline)( INTEGER(N),
- REAL_ARRAY(X),
- REAL_ARRAY(Y),
- REAL_ARRAY(Z) ){
- GENPTR_INTEGER(N)
- GENPTR_REAL_ARRAY(X)
- GENPTR_REAL_ARRAY(Y)
- GENPTR_REAL_ARRAY(Z)
- return astG3DLine( *N, X, Y, Z ) ? F77_TRUE : F77_FALSE;
-
-}
-
-
-F77_INTEGER_FUNCTION(ast_g3dtext)( CHARACTER(TEXT),
- REAL_ARRAY(REF),
- CHARACTER(JUST),
- REAL_ARRAY(UP),
- REAL_ARRAY(NORM)
- TRAIL(TEXT)
- TRAIL(JUST) ){
- GENPTR_CHARACTER(TEXT)
- GENPTR_REAL_ARRAY(REF)
- GENPTR_CHARACTER(JUST)
- GENPTR_REAL_ARRAY(UP)
- GENPTR_REAL_ARRAY(NORM)
- F77_INTEGER_TYPE(RESULT);
- char *text, *just, *p;
-
- text = astString( TEXT, TEXT_length );
- just = astString( JUST, JUST_length );
-
-/* Ignore trailing spaces in the text */
- p = text + TEXT_length;
- while( !*p || *p == ' ' ) *(p--) = 0;
-
- if( astOK ) {
- RESULT = (F77_INTEGER_TYPE) astG3DText( text, REF, just, UP, NORM );
- } else {
- RESULT = 0;
- }
-
- (void) astFree( text );
- (void) astFree( just );
-
- return RESULT;
-}
-
-F77_INTEGER_FUNCTION(ast_g3dtxext)( CHARACTER(TEXT),
- REAL_ARRAY(REF),
- CHARACTER(JUST),
- REAL_ARRAY(UP),
- REAL_ARRAY(NORM),
- REAL_ARRAY(XB),
- REAL_ARRAY(YB),
- REAL_ARRAY(ZB),
- REAL_ARRAY(BL)
- TRAIL(TEXT)
- TRAIL(JUST) ){
- GENPTR_CHARACTER(TEXT)
- GENPTR_REAL_ARRAY(REF)
- GENPTR_CHARACTER(JUST)
- GENPTR_REAL_ARRAY(UP)
- GENPTR_REAL_ARRAY(NORM)
- GENPTR_REAL_ARRAY(XB)
- GENPTR_REAL_ARRAY(YB)
- GENPTR_REAL_ARRAY(ZB)
- GENPTR_REAL_ARRAY(BL)
- F77_INTEGER_TYPE(RESULT);
- char *text, *just, *p;
-
- text = astString( TEXT, TEXT_length );
- just = astString( JUST, JUST_length );
-
-/* Ignore trailing spaces in the text */
- p = text + TEXT_length;
- while( !*p || *p == ' ' ) *(p--) = 0;
-
- if( astOK ) {
- RESULT = (F77_INTEGER_TYPE) astG3DTxExt( text, REF, just, UP, NORM,
- XB, YB, ZB, BL );
- } else {
- RESULT = 0;
- }
-
- (void) astFree( text );
- (void) astFree( just );
-
- return RESULT;
-}
-
-