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