1 #if !defined( POINTSET_INCLUDED ) /* Include this file only once */
2 #define POINTSET_INCLUDED
3 /*
4 *+
5 *  Name:
6 *     pointset.h
7 
8 *  Type:
9 *     C include file.
10 
11 *  Purpose:
12 *     Define the interface to the PointSet class.
13 
14 *  Invocation:
15 *     #include "pointset.h"
16 
17 *  Description:
18 *     This include file defines the interface to the PointSet class
19 *     and provides the type definitions, function prototypes and
20 *     macros, etc.  needed to use this class.
21 *
22 *     The PointSet class encapsulates sets of coordinate values
23 *     representing points in an N-dimensional space, to which
24 *     coordinate transformations may be applied. It also provides
25 *     memory allocation facilities for coordinate values.
26 
27 *  Inheritance:
28 *     The PointSet class inherits from the Object class.
29 
30 *  Attributes Over-Ridden:
31 *     None.
32 
33 *  New Attributes Defined:
34 *     Ncoord (integer)
35 *        A read-only attribute that gives the number of coordinates
36 *        for each point in a PointSet (i.e. the number of dimensions
37 *        of the space in which the points reside). This value is
38 *        determined when the PointSet is created.
39 *     Npoint (integer)
40 *        A read-only attribute that gives the number of points that
41 *        can be stored in the PointSet. This value is determined when
42 *        the PointSet is created.
43 *     PointAccuracy (floating point)
44 *        This stores the absolute accuracies for each axis in the PointSet.
45 
46 *  Methods Over-Ridden:
47 *     Public:
48 *        None.
49 *
50 *     Protected:
51 *        ClearAttrib
52 *           Clear an attribute value for a PointSet.
53 *        GetAttrib
54 *           Get an attribute value for a PointSet.
55 *        SetAttrib
56 *           Set an attribute value for a PointSet.
57 *        TestAttrib
58 *           Test if an attribute value has been set for a PointSet.
59 
60 *  New Methods Defined:
61 *     Public:
62 *        astAppendPoints
63 *           Append one PointSet to another.
64 *        astBndPoints
65 *           Find the axis bounds of the points in a PointSet.
66 *        astGetPoints
67 *           Get a pointer to the coordinate values associated with a PointSet.
68 *        astPermPoints
69 *           Permute coordinates within a PointSet.
70 *        astSetPoints
71 *           Associate coordinate values with a PointSet.
72 *        astSetNpoint
73 *           Reduce the size of a PointSet.
74 *        astSetSubPoints
75 *           Associate one PointSet with a subset of another.
76 *
77 *     Protected:
78 *        astGetNpoint
79 *           Get the number of points in a PointSet.
80 *        astGetNcoord
81 *           Get the number of coordinate values per point from a PointSet.
82 *        astGetPointAccuracy
83 *           Get the curent value of the PointAcuracy attribute for an axis.
84 *        astSetPointAccuracy
85 *           Set a new value for the PointAcuracy attribute for an axis.
86 *        astTestPointAccuracy
87 *           Test the value of the PointAcuracy attribute for an axis.
88 *        astClearPointAccuracy
89 *           Clear the value of the PointAcuracy attribute for an axis.
90 
91 *  Other Class Functions:
92 *     Public:
93 *        astIsAPointSet
94 *           Test class membership.
95 *        astPointSet
96 *           Create a PointSet.
97 *
98 *     Protected:
99 *        astCheckPointSet
100 *           Validate class membership.
101 *        astInitPointSet
102 *           Initialise a PointSet.
103 *        astInitPointSetVtab
104 *           Initialise the virtual function table for the PointSet class.
105 *        astLoadPointSet
106 *           Load a PointSet.
107 
108 *  Macros:
109 *     Public:
110 *        AST__BAD
111 *           Bad value flag for coordinate data.
112 *
113 *     Protected:
114 *        astISBAD
115 *           Check if a value is AST__BAD or NaN.
116 *        astISGOOD
117 *           Check if a value is not AST__BAD or NaN.
118 *        astISNAN
119 *           Check if a value is NaN.
120 
121 *  Type Definitions:
122 *     Public:
123 *        AstPointSet
124 *           PointSet object type.
125 *
126 *     Protected:
127 *        AstPointSetVtab
128 *           PointSet virtual function table type.
129 
130 *  Feature Test Macros:
131 *     astCLASS
132 *        If the astCLASS macro is undefined, only public symbols are
133 *        made available, otherwise protected symbols (for use in other
134 *        class implementations) are defined. This macro also affects
135 *        the reporting of error context information, which is only
136 *        provided for external calls to the AST library.
137 
138 *  Copyright:
139 *     Copyright (C) 1997-2006 Council for the Central Laboratory of the
140 *     Research Councils
141 
142 *  Licence:
143 *     This program is free software: you can redistribute it and/or
144 *     modify it under the terms of the GNU Lesser General Public
145 *     License as published by the Free Software Foundation, either
146 *     version 3 of the License, or (at your option) any later
147 *     version.
148 *
149 *     This program is distributed in the hope that it will be useful,
150 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
151 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152 *     GNU Lesser General Public License for more details.
153 *
154 *     You should have received a copy of the GNU Lesser General
155 *     License along with this program.  If not, see
156 *     <http://www.gnu.org/licenses/>.
157 
158 *  Authors:
159 *     RFWS: R.F. Warren-Smith (Starlink)
160 *     DSB: David S. Berry (Starlink)
161 
162 *  History:
163 *     30-JAN-1996 (RFWS):
164 *        Original version.
165 *     27-SEP-1996 (RFWS):
166 *        Added external interface and I/O facilities.
167 *     8-JAN-2003 (DSB):
168 *        Added protected astInitPointSetVtab method.
169 *     2-NOV-2004 (DSB):
170 *        Added PointAccuracy attribute.
171 *-
172 */
173 
174 /* Include files. */
175 /* ============== */
176 
177 /* Configuration results. */
178 /* ---------------------- */
179 #if HAVE_CONFIG_H
180 #include <config.h>
181 #endif
182 
183 /* Interface definitions. */
184 /* ---------------------- */
185 #include "object.h"              /* Base Object class */
186 
187 /* C header files. */
188 /* --------------- */
189 #include <float.h>
190 #if defined(astCLASS)            /* Protected */
191 #include <stddef.h>
192 #include <math.h>
193 
194 #if !HAVE_DECL_ISNAN
195 #  if HAVE_ISNAN
196      /* Seems that math.h does not include a prototype for isnan etc */
197      int isnan( double );
198 #  else
199      /* isnan is not available prior to C99 so define
200         alternative macros Note multiple evaluations of "x" in these
201         macros!!! */
202 #    define isnan(x) ((x) != (x))
203 #  endif
204 #endif
205 
206 #if !HAVE_DECL_ISFINITE
207 #  if HAVE_ISFINITE
208      /* Seems that math.h does not include a prototype for isfinite */
209      int isfinite( double );
210 #  else
211      /* isfinite is not available prior to C99 so define
212         alternative macros. Note multiple evaluations of "x" in these
213         macros!!! */
214 #    define isfinite(x) (!isnan(x) && ((x) != (1.0/0.0)) && ((x) != (-1.0/0.0)))
215 #  endif
216 #endif
217 #endif
218 
219 /* Macros. */
220 /* ======= */
221 #if defined(astCLASS) || defined(astFORTRAN77)
222 #define STATUS_PTR status
223 #else
224 #define STATUS_PTR astGetStatusPtr
225 #endif
226 
227 /*
228 *+
229 *  Name:
230 *     AST__BAD
231 
232 *  Type:
233 *     Public macro.
234 
235 *  Purpose:
236 *     Bad value flag for coordinate data.
237 
238 *  Synopsis:
239 *     #include "pointset.h"
240 *     const double AST__BAD
241 
242 *  Class Membership:
243 *     Defined by the PointSet class.
244 
245 *  Description:
246 *     This macro expands to a const double value that is used to flag
247 *     coordinate values that are "bad" (i.e. undefined or
248 *     meaningless). Classes that implement coordinate transformations
249 *     should test coordinate values against this value, and
250 *     appropriately propagate bad values to their output.
251 *-
252 */
253 
254 /* Define AST__BAD to be the most negative (normalised) double
255    value. */
256 
257 #define AST__BAD (-(DBL_MAX))
258 
259 /*
260 *+
261 *  Name:
262 *     AST__NAN
263 
264 *  Type:
265 *     Public macro.
266 
267 *  Purpose:
268 *     A value representing the double precision IEEE NaN value.
269 
270 *  Synopsis:
271 *     #include "pointset.h"
272 *     const double AST__NAN
273 
274 *  Class Membership:
275 *     Defined by the PointSet class.
276 
277 *  Description:
278 *     This macro expands to a const double value that is used to indicate
279 *     that a IEEE NaN value should be used. Note, AST__NAN itself is a finite
280 *     double precision floating point value a little below the maximum
281 *     allowed value for a double. This value can be used as flag to
282 *     indicate that the corresponding IEEE NaN value should be used in its
283 *     place.
284 
285 *-
286 */
287 #define AST__NAN (-(0.95*DBL_MAX))
288 
289 /*
290 *+
291 *  Name:
292 *     AST__NANF
293 
294 *  Type:
295 *     Public macro.
296 
297 *  Purpose:
298 *     A value representing the single precision IEEE NaN value.
299 
300 *  Synopsis:
301 *     #include "pointset.h"
302 *     const double AST__NANF
303 
304 *  Class Membership:
305 *     Defined by the PointSet class.
306 
307 *  Description:
308 *     This macro expands to a const float value that is used to indicate
309 *     that a IEEE NaN value should be used. Note, AST__NANF itself is a finite
310 *     single precision floating point value a little below the maximum
311 *     allowed value for a float. This value can be used as flag to
312 *     indicate that the corresponding IEEE NaN value should be used in its
313 *     place.
314 
315 *-
316 */
317 #define AST__NANF ((float)-(0.95*FLT_MAX))
318 
319 #if defined(astCLASS)            /* Protected */
320 
321 /*
322 *+
323 *  Name:
324 *     astISNAN
325 
326 *  Type:
327 *     Protected macro.
328 
329 *  Purpose:
330 *     Test if a double is NaN.
331 
332 *  Synopsis:
333 *     #include "pointset.h"
334 *     astISNAN(value)
335 
336 *  Class Membership:
337 *     Defined by the PointSet class.
338 
339 *  Description:
340 *     This macro expands to a integer valued expression which is zero
341 *     if and only if the supplied value equals NaN ("Not a Number").
342 
343 *  Parameters:
344 *     value
345 *        The value to be tested. This should be a double.
346 
347 *  Examples:
348 *     if( astISNAN(x) ) x = AST__BAD;
349 *        If "x" is NaN replace it with AST__BAD.
350 
351 *  Notes:
352 *     - To avoid problems with some compilers, you should not leave
353 *     any white space around the macro arguments.
354 *     - On some system it is possible that the supplied macro argument
355 *     "x" may be evaluated multiple times. Therefore the evaluation of "x"
356 *     should have no side effects.
357 *-
358 */
359 
360 #define astISNAN(value) isnan(value)
361 
362 /*
363 *+
364 *  Name:
365 *     astISFINITE
366 
367 *  Type:
368 *     Protected macro.
369 
370 *  Purpose:
371 *     Test if a double is neither NaN nor Inf.
372 
373 *  Synopsis:
374 *     #include "pointset.h"
375 *     astISFINITE(value)
376 
377 *  Class Membership:
378 *     Defined by the PointSet class.
379 
380 *  Description:
381 *     This macro expands to a integer valued expression which is zero
382 *     if and only if the supplied value equals NaN ("Not a Number") or Inf.
383 
384 *  Parameters:
385 *     value
386 *        The value to be tested. This should be a double.
387 
388 *  Examples:
389 *     if( !astISFINITE(x) ) x = AST__BAD;
390 *        If "x" is NaN or Inf replace it with AST__BAD.
391 
392 *  Notes:
393 *     - To avoid problems with some compilers, you should not leave
394 *     any white space around the macro arguments.
395 *     - On some system it is possible that the supplied macro argument
396 *     "x" may be evaluated multiple times. Therefore the evaluation of "x"
397 *     should have no side effects.
398 *-
399 */
400 
401 #define astISFINITE(value) isfinite(value)
402 
403 /*
404 *+
405 *  Name:
406 *     astISGOOD
407 
408 *  Type:
409 *     Protected macro.
410 
411 *  Purpose:
412 *     Test if a double is neither AST__BAD, NaN or Inf.
413 
414 *  Synopsis:
415 *     #include "pointset.h"
416 *     astISGOOD(value)
417 
418 *  Class Membership:
419 *     Defined by the PointSet class.
420 
421 *  Description:
422 *     This macro expands to a integer valued expression which is zero
423 *     if and only if the supplied value equals AST__BAD or is NaN ("Not a
424 *     Number") or "Inf".
425 
426 *  Parameters:
427 *     value
428 *        The value to be tested. This should be a double.
429 
430 *  Examples:
431 *     if( astISGOOD(x) ) y = x;
432 *        Checks that "x" is usable before assigning it to y.
433 
434 *  Notes:
435 *     - To avoid problems with some compilers, you should not leave
436 *     any white space around the macro arguments.
437 *     - On some system it is possible that the supplied macro argument
438 *     "x" may be evaluated multiple times. Therefore the evaluation of "x"
439 *     should have no side effects.
440 *-
441 */
442 
443 #define astISGOOD(value) ( (value) != AST__BAD && astISFINITE(value) )
444 
445 
446 /*
447 *+
448 *  Name:
449 *     astISBAD
450 
451 *  Type:
452 *     Protected macro.
453 
454 *  Purpose:
455 *     Test if a double is either AST__BAD, NaN, or Inf.
456 
457 *  Synopsis:
458 *     #include "pointset.h"
459 *     astISBAD(value)
460 
461 *  Class Membership:
462 *     Defined by the PointSet class.
463 
464 *  Description:
465 *     This macro expands to a integer valued expression which is non-zero
466 *     if and only if the supplied value equals AST__BAD or is NaN ("Not a
467 *     Number"), or is Inf.
468 
469 *  Parameters:
470 *     value
471 *        The value to be tested. This should be a double.
472 
473 *  Examples:
474 *     if( astISBAD(x) ) astError( ... );
475 *        Reports an error if "x" is bad.
476 
477 *  Notes:
478 *     - To avoid problems with some compilers, you should not leave
479 *     any white space around the macro arguments.
480 *     - On some system it is possible that the supplied macro argument
481 *     "x" may be evaluated multiple times. Therefore the evaluation of "x"
482 *     should have no side effects.
483 *-
484 */
485 
486 #define astISBAD(value) ( (value) == AST__BAD || !astISFINITE(value))
487 
488 #endif
489 
490 /* Define a dummy __attribute__ macro for use on non-GNU compilers. */
491 #ifndef __GNUC__
492 #  define  __attribute__(x)  /*NOTHING*/
493 #endif
494 
495 /* Type Definitions. */
496 /* ================= */
497 /* PointSet structure. */
498 /* ------------------- */
499 /* This structure contains all information that is unique to each object in
500    the class (e.g. its instance variables). */
501 typedef struct AstPointSet {
502 
503 /* Attributes inherited from the parent class. */
504    AstObject object;             /* Parent class structure */
505 
506 /* Attributes specific to objects in this class. */
507    double **ptr;                 /* Pointer to array of pointers to values */
508    double *values;               /* Pointer to array of coordinate values */
509    int ncoord;                   /* Number of coordinate values per point */
510    int npoint;                   /* Number of points */
511    double *acc;                  /* Axis accuracies */
512 } AstPointSet;
513 
514 /* Virtual function table. */
515 /* ----------------------- */
516 /* This table contains all information that is the same for all
517    objects in the class (e.g. pointers to its virtual functions). */
518 #if defined(astCLASS)            /* Protected */
519 typedef struct AstPointSetVtab {
520 
521 /* Properties (e.g. methods) inherited from the parent class. */
522    AstObjectVtab object_vtab;    /* Parent class virtual function table */
523 
524 /* A Unique identifier to determine class membership. */
525    AstClassIdentifier id;
526 
527 /* Properties (e.g. methods) specific to this class. */
528    AstPointSet *(* AppendPoints)( AstPointSet *, AstPointSet *, int * );
529    double **(* GetPoints)( AstPointSet *, int * );
530    int (* GetNcoord)( const AstPointSet *, int * );
531    int (* GetNpoint)( const AstPointSet *, int * );
532    void (* BndPoints)( AstPointSet *, double *, double *, int * );
533    void (* PermPoints)( AstPointSet *, int, const int[], int * );
534    void (* SetNpoint)( AstPointSet *, int, int * );
535    void (* SetPoints)( AstPointSet *, double **, int * );
536    void (* SetSubPoints)( AstPointSet *, int, int, AstPointSet *, int * );
537    int (* ReplaceNaN)( AstPointSet *, int * );
538 
539    double (* GetPointAccuracy)( AstPointSet *, int, int * );
540    int (* TestPointAccuracy)( AstPointSet *, int, int * );
541    void (* ClearPointAccuracy)( AstPointSet *, int, int * );
542    void (* SetPointAccuracy)( AstPointSet *, int, double, int * );
543 
544 } AstPointSetVtab;
545 
546 #if defined(THREAD_SAFE)
547 
548 /* Define a structure holding all data items that are global within this
549    class. */
550 typedef struct AstPointSetGlobals {
551    AstPointSetVtab Class_Vtab;
552    int Class_Init;
553    char GetAttrib_Buff[ 101 ];
554 } AstPointSetGlobals;
555 
556 #endif
557 
558 #endif
559 
560 /* Function prototypes. */
561 /* ==================== */
562 /* Prototypes for standard class functions. */
563 /* ---------------------------------------- */
564 astPROTO_CHECK(PointSet)         /* Check class membership */
565 astPROTO_ISA(PointSet)           /* Test class membership */
566 
567 /* Constructor. */
568 #if defined(astCLASS)            /* Protected. */
569 AstPointSet *astPointSet_( int, int, const char *, int *, ...);
570 #else
571 AstPointSet *astPointSetId_( int, int, const char *, ... )__attribute__((format(printf,3,4)));
572 #endif
573 
574 #if defined(astCLASS)            /* Protected */
575 
576 /* Initialiser. */
577 AstPointSet *astInitPointSet_( void *, size_t, int, AstPointSetVtab *,
578                                const char *, int, int, int * );
579 
580 /* Vtab initialiser. */
581 void astInitPointSetVtab_( AstPointSetVtab *, const char *, int * );
582 
583 /* Loader. */
584 AstPointSet *astLoadPointSet_( void *, size_t, AstPointSetVtab *,
585                                const char *, AstChannel *, int * );
586 
587 /* Thread-safe initialiser for all global data used by this module. */
588 #if defined(THREAD_SAFE)
589 void astInitPointSetGlobals_( AstPointSetGlobals * );
590 #endif
591 
592 #endif
593 
594 /* Prototypes for member functions. */
595 /* -------------------------------- */
596 double **astGetPoints_( AstPointSet *, int * );
597 void astPermPoints_( AstPointSet *, int, const int[], int * );
598 void astSetPoints_( AstPointSet *, double **, int * );
599 void astSetNpoint_( AstPointSet *, int, int * );
600 void astSetSubPoints_( AstPointSet *, int, int, AstPointSet *, int * );
601 AstPointSet *astAppendPoints_( AstPointSet *, AstPointSet *, int * );
602 void astBndPoints_( AstPointSet *, double *, double *, int * );
603 int astReplaceNaN_( AstPointSet *, int * );
604 
605 # if defined(astCLASS)           /* Protected */
606 int astGetNcoord_( const AstPointSet *, int * );
607 int astGetNpoint_( const AstPointSet *, int * );
608 
609 double astGetPointAccuracy_( AstPointSet *, int, int * );
610 int astTestPointAccuracy_( AstPointSet *, int, int * );
611 void astClearPointAccuracy_( AstPointSet *, int, int * );
612 void astSetPointAccuracy_( AstPointSet *, int, double, int * );
613 
614 double astCheckNaN_( double );
615 float astCheckNaNF_( float );
616 
617 #endif
618 
619 /* Function interfaces. */
620 /* ==================== */
621 /* These macros are wrap-ups for the functions defined by this class
622    to make them easier to invoke (e.g. to avoid type mis-matches when
623    passing pointers to objects from derived classes). */
624 
625 /* Interfaces to standard class functions. */
626 /* --------------------------------------- */
627 /* Some of these functions provide validation, so we cannot use them
628    to validate their own arguments. We must use a cast when passing
629    object pointers (so that they can accept objects from derived
630    classes). */
631 
632 /* Check class membership. */
633 #define astCheckPointSet(this) astINVOKE_CHECK(PointSet,this,0)
634 #define astVerifyPointSet(this) astINVOKE_CHECK(PointSet,this,1)
635 
636 /* Test class membership. */
637 #define astIsAPointSet(this) astINVOKE_ISA(PointSet,this)
638 
639 /* Constructor. */
640 #if defined(astCLASS)            /* Protected. */
641 #define astPointSet astINVOKE(F,astPointSet_)
642 #else
643 #define astPointSet astINVOKE(F,astPointSetId_)
644 #endif
645 
646 #if defined(astCLASS)            /* Protected */
647 
648 /* Initialiser. */
649 #define astInitPointSet(mem,size,init,vtab,name,npoint,ncoord) \
650 astINVOKE(O,astInitPointSet_(mem,size,init,vtab,name,npoint,ncoord,STATUS_PTR))
651 
652 /* Vtab Initialiser. */
653 #define astInitPointSetVtab(vtab,name) astINVOKE(V,astInitPointSetVtab_(vtab,name,STATUS_PTR))
654 /* Loader. */
655 #define astLoadPointSet(mem,size,vtab,name,channel) \
656 astINVOKE(O,astLoadPointSet_(mem,size,vtab,name,astCheckChannel(channel),STATUS_PTR))
657 #endif
658 
659 /* Interfaces to public member functions. */
660 /* -------------------------------------- */
661 /* Here we make use of astCheckPointSet to validate PointSet pointers
662    before use.  This provides a contextual error report if a pointer
663    to the wrong sort of Object is supplied. */
664 
665 #define astGetPoints(this) \
666 astINVOKE(V,astGetPoints_(astCheckPointSet(this),STATUS_PTR))
667 #define astPermPoints(this,forward,perm) \
668 astINVOKE(V,astPermPoints_(astCheckPointSet(this),forward,perm,STATUS_PTR))
669 #define astSetPoints(this,ptr) \
670 astINVOKE(V,astSetPoints_(astCheckPointSet(this),ptr,STATUS_PTR))
671 #define astSetNpoint(this,np) \
672 astINVOKE(V,astSetNpoint_(astCheckPointSet(this),np,STATUS_PTR))
673 #define astSetSubPoints(point1,point,coord,point2) \
674 astINVOKE(V,astSetSubPoints_(astCheckPointSet(point1),point,coord,astCheckPointSet(point2),STATUS_PTR))
675 #define astAppendPoints(this,that) \
676 astINVOKE(O,astAppendPoints_(astCheckPointSet(this),astCheckPointSet(that),STATUS_PTR))
677 #define astBndPoints(this,lbnd,ubnd) \
678 astINVOKE(V,astBndPoints_(astCheckPointSet(this),lbnd,ubnd,STATUS_PTR))
679 #define astReplaceNaN(this) \
680 astINVOKE(V,astReplaceNaN_(astCheckPointSet(this),STATUS_PTR))
681 
682 #if defined(astCLASS)            /* Protected */
683 #define astGetNpoint(this) \
684 astINVOKE(V,astGetNpoint_(astCheckPointSet(this),STATUS_PTR))
685 #define astGetNcoord(this) \
686 astINVOKE(V,astGetNcoord_(astCheckPointSet(this),STATUS_PTR))
687 
688 #define astClearPointAccuracy(this,axis) \
689 astINVOKE(V,astClearPointAccuracy_(astCheckPointSet(this),axis,STATUS_PTR))
690 #define astGetPointAccuracy(this,axis) \
691 astINVOKE(V,astGetPointAccuracy_(astCheckPointSet(this),axis,STATUS_PTR))
692 #define astSetPointAccuracy(this,axis,value) \
693 astINVOKE(V,astSetPointAccuracy_(astCheckPointSet(this),axis,value,STATUS_PTR))
694 #define astTestPointAccuracy(this,axis) \
695 astINVOKE(V,astTestPointAccuracy_(astCheckPointSet(this),axis,STATUS_PTR))
696 
697 #define astCheckNaNF(value) astCheckNaNF_(value)
698 #define astCheckNaN(value) astCheckNaN_(value)
699 
700 
701 #endif
702 #endif
703 
704 
705 
706 
707 
708