This is MiscCoord.m in view mode; [Download] [Up]
/*=============================== MiscCoord.m ===============================*/ /* MiscCoord class contains and supports double precision floating point values representing locations in a three dimensional coordinate system. DMA Release 0.8, Copyright @1993 by Genesis Project, Ltd. All Rights Reserved. For further information on terms and conditions see the MiscKit license. HISTORY 22-Feb-93 Dale Amon at GPL Created. */ #import <MiscFoundation/MiscCoord.h> #import <objc/Storage.h> #ifdef WIN32 #define M_PI 3.14159265358979323846 #endif @implementation MiscCoord /*===========================================================================*/ /* Class methods */ /*===========================================================================*/ /* Initialize the class */ + (void)initialize {[MiscCoord setVersion:MISC_COORD_VERSION_ID]; return;} + (unsigned int) dimensions {return MISC_DIMENSIONS;} /*===========================================================================*/ /* Class: basic argument conversions */ /*===========================================================================*/ /* convert from r.rrr radians degrees to ddd.ddd degrees */ +(double) radiansToDegrees: (double)angle { double deg = angle * MISC_DEGREES_PER_RADIAN; return ((deg<0.0) ? deg - MISC_ROUND_OFF : deg + MISC_ROUND_OFF); } /*---------------------------------------------------------------------------*/ /* convert from ddd.ddd degrees to r.rrr radians. It is rounded up slightly to correct for the slight numerical error that crops up due to the multiplication by an approximation to pi. */ +(double) degreesToRadians: (double) angle {return (angle * MISC_RADIANS_PER_DEGREE);} /*---------------------------------------------------------------------------*/ /* convert degrees from ddd:mm:ss.ss to ddd.ddd */ +(double) toDegreesOnlyDegrees: (double) deg minutes: (double) min seconds: (double) sec {return (deg + min/60.0 + sec/3600.0);} /*---------------------------------------------------------------------------*/ /* Convert degrees from ddd.ddd to ddd:mm:ss.ss Handles negative values by making degrees positive and replacing the negative sign on each resultant value of deg,min,sec. */ +(double) fromDegreesOnly: (double) degrees degrees: (double *) deg minutes: (double *) min seconds: (double *) sec { double remainder,sign; sign = (degrees<0.0) ? -1.0 : 1.0; degrees = sign * degrees; *deg = floor(degrees); remainder = (degrees - *deg) * 60; *min = floor(remainder); *sec = (remainder - *min) * 60; *deg *= sign; *min *= sign; *sec *= sign; return degrees; } /*===========================================================================*/ /* Initialization methods */ /*===========================================================================*/ /* DESIGNATED INITIALIZER: Creates and explicitely inits a three dimensional map or globe coordinate. Default size is one point, but point storage will be allocated on demand. The initial point The default block is the one initial point. */ -initDescription: (NSString *) txt converter: (id <MiscCoordConverterServer>) aConverter constants: anObject { [super init]; curIndex = 0; curBlockSize = MISC_DEFAULT_POINT_CAPACITY; constants = anObject; converter = aConverter; pntStorage = [[Storage alloc] // can't use our zone: NXZone!=NSZone initCount: MISC_DEFAULT_POINT_CAPACITY elementSize: MISC_DIMENSIONS * sizeof(double) description: MISC_ELEMENT_DESCRIPTION]; [self setDescription: txt]; return self; } /*---------------------------------------------------------------------------*/ /* Creates and explicitely inits a three dimensional map or globe coordinate to the origin. This should be overridden by the subclass because it creates an coord object that is unmappable to another coord system. */ -init {return ([self initDescription: (NSString*)nil converter: nil constants: nil]);} /*---------------------------------------------------------------------------*/ /* free the storage and description before freeing self. Constants and converters are freed because either the object is unique to one MiscCoord, in which case it should be locally deleted, or else it is shared in which case it should have free blocked. It is one or the other. */ - (void)dealloc { [pntStorage free]; [constants release]; [(id)converter release]; if (description) free((void*)description); [super dealloc]; } /*===========================================================================*/ /* Description handling methods */ /*===========================================================================*/ - setDescription: (NSString *) txt { [description autorelease]; description = [txt copy]; return self; } - (NSString *) description {return ( description);} /*===========================================================================*/ /* Conversion converter and constants methods */ /*===========================================================================*/ - (id <MiscCoordConverterServer>) converter {return converter;} - constants {return constants;} /*===========================================================================*/ /* Current point and storage management methods Select a block of points using the index of a starting point and a count of the number of points required after that index. Manage storage requirement for the requested blocks. */ /*===========================================================================*/ /* If the index is out of range, return NO, otherwise return YES. If the blockSize would include out of range points, modify it to be in range. Does not modify the MiscCoord storage. */ - (BOOL) selectExistingPoints: (unsigned int) n blockSize: (unsigned int) m { unsigned int availableSize, requiredSize; availableSize = [pntStorage count]; requiredSize = n + m; if (n >= availableSize) return NO; curIndex = n; curBlockSize = (requiredSize<=availableSize) ? m : availableSize - n; return YES; } /*---------------------------------------------------------------------------*/ /* Resize so that the capacity is exactly sufficient to hold a block ending at n+m. Either expands or truncates the MiscCoord data storage Note: May invalidate pointers to data. Always assume that it does. */ - (BOOL) selectAndSetNumPoints: (unsigned int) n blockSize: (unsigned int) m { [pntStorage setNumSlots:n+m]; curIndex = n; curBlockSize = m; return YES; } /*---------------------------------------------------------------------------*/ /* Resize so that the capacity is sufficient to hold a block ending at n+m. Expands the MiscCoord data storage if necessary. Never contracts the storage. Note: May invalidate pointers to data. Always assume that it does. */ - (BOOL) selectAndSetMinPoints: (unsigned int) n blockSize: (unsigned int) m { if (n+m > [pntStorage count]) [pntStorage setNumSlots:n+m]; curIndex = n; curBlockSize = m; return YES; } /*---------------------------------------------------------------------------*/ /* Return the current Point, BlockSize or capacity. */ - (unsigned int) curIndex {return curIndex;} - (unsigned int) curBlockSize {return curBlockSize;} - (unsigned int) numPoints {return [pntStorage count];} /*===========================================================================*/ /* Storage management methods */ /*===========================================================================*/ /* return a pointer to the actual stored data of the currently selected block of points. This should ONLY be used by converters that need to iterate over data in a fast and efficient manner. The data pointer can is only valid if nothing causes the size of the array to change while you posses it. CAVEAT EMPTOR. */ -(double *) curPtr {return ((double *) [pntStorage elementAt:curIndex]);} /*===========================================================================*/ /* Coordinate handling methods */ /*===========================================================================*/ /* set Coord value */ -setCoord:(double) c1 : (double) c2 : (double) c3 { double *ptr; ptr = (double *)[pntStorage elementAt: curIndex]; ptr[0] = c1; ptr[1] = c2; ptr[2] = c3; return self; } /*---------------------------------------------------------------------------*/ /* get Coord value */ - coord: (double*) c1 : (double*) c2 : (double*) c3; { double *ptr; ptr = (double *)[pntStorage elementAt: curIndex]; *c1 = ptr[0]; *c2 = ptr[1]; *c3 = ptr[2]; return self; } /*---------------------------------------------------------------------------*/ /* Individually request coord values at current Index */ -(double) coord1 {return ((double *)[pntStorage elementAt:curIndex])[0];} -(double) coord2 {return ((double *)[pntStorage elementAt:curIndex])[1];} -(double) coord3 {return ((double *)[pntStorage elementAt:curIndex])[2];} /*===========================================================================*/ /* Conversion methods */ /*===========================================================================*/ /* Copy or convert the entire MiscCoord from source to destination with assistance of a converter. If we succeed, also copy the text description to the destination. */ -(BOOL) convertCoord: (id <MiscCoordConverterClient>) aCoord { if (converter) {[self selectAndSetMinPoints: 0 blockSize: [pntStorage count]]; [(id)aCoord selectAndSetMinPoints: curIndex blockSize: curBlockSize]; if ([converter convert: self to: aCoord]) {[(id)aCoord setDescription: description]; return YES; } } return NO; } /*---------------------------------------------------------------------------*/ /* Send our selected block of points to the converter and have the result stored in the selected block in the target coord. */ -(BOOL) convert: (id <MiscCoordConverterClient>) aCoord { if (converter) return [converter convert: self to: aCoord]; return NO; } /*===========================================================================*/ /* Archive methods */ /*===========================================================================*/ - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeValuesOfObjCTypes:"*ii", description, (int*)&curIndex, (int*)&curBlockSize]; [aCoder encodeObject:constants]; [aCoder encodeObject:converter]; [aCoder encodeObject:(id)pntStorage]; } /*---------------------------------------------------------------------------*/ - (id)initWithCoder:(NSCoder *)aDecoder { [aDecoder decodeValuesOfObjCTypes:"*ii", description, (int*)&curIndex, (int*)&curBlockSize]; constants = [[aDecoder decodeObject] retain]; converter = (id <MiscCoordConverterServer>) [[aDecoder decodeObject] retain]; pntStorage = (Storage*) [[aDecoder decodeObject] retain]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.