This is MorphLine.m in view mode; [Download] [Up]
// MorphLine.m // // created by Martin Wennerberg on Sun 12-Nov-1995 // // when who modification #import "MorphLine.h" #import "algebra.h" @implementation MorphLine - init { self = [super init]; nPoints = 2; startPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint)); endPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint)); moveStartDelta = 0.0; moveEndDelta = 1.0; dissolveStartDelta = 0.0; dissolveEndDelta = 1.0; return self; } - initWithValuesInDict:(NSDictionary *)dict { NSArray *startPointsValues; NSArray *endPointsValues; NSNumber *number; self = [self init]; if ([dict isKindOfClass:[NSString class]]) dict = [(NSString *)dict propertyList]; startPointsValues = [dict objectForKey:MLKEY_STARTPOINTS]; endPointsValues = [dict objectForKey:MLKEY_ENDPOINTS]; if (MIN([startPointsValues count], [endPointsValues count]) >= 2) { unsigned i; nPoints = MIN([startPointsValues count], [endPointsValues count]); free (startPoints); free (endPoints); startPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint)); endPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint)); for (i = 0; i < nPoints; ++i) { startPoints[i] = NSPointFromString([startPointsValues objectAtIndex:i]); endPoints[i] = NSPointFromString([endPointsValues objectAtIndex:i]); } } number = [dict objectForKey:MLKEY_MOVESTART]; if (number != nil) [self setMoveStartDelta:[number floatValue]]; number = [dict objectForKey:MLKEY_MOVEEND]; if (number != nil) [self setMoveEndDelta:[number floatValue]]; number = [dict objectForKey:MLKEY_DISSOLVESTART]; if (number != nil) [self setDissolveStartDelta:[number floatValue]]; number = [dict objectForKey:MLKEY_DISSOLVEEND]; if (number != nil) [self setDissolveEndDelta:[number floatValue]]; return self; } - (NSDictionary *)pList { NSMutableDictionary *dict; NSMutableArray *startPointStrings; NSMutableArray *endPointStrings; unsigned i; dict = [NSMutableDictionary dictionaryWithCapacity:10]; startPointStrings = [NSMutableArray arrayWithCapacity:nPoints]; endPointStrings = [NSMutableArray arrayWithCapacity:nPoints]; for (i = 0; i < nPoints; ++i) { [startPointStrings addObject:NSStringFromPoint(startPoints[i])]; [endPointStrings addObject:NSStringFromPoint(endPoints[i])]; } [dict setObject:startPointStrings forKey:MLKEY_STARTPOINTS]; [dict setObject:endPointStrings forKey:MLKEY_ENDPOINTS]; [dict setObject:[[NSNumber numberWithFloat:[self moveStartDelta]] description] forKey:MLKEY_MOVESTART]; [dict setObject:[[NSNumber numberWithFloat:[self moveEndDelta]] description] forKey:MLKEY_MOVEEND]; [dict setObject:[[NSNumber numberWithFloat:[self dissolveStartDelta]] description] forKey:MLKEY_DISSOLVESTART]; [dict setObject:[[NSNumber numberWithFloat:[self dissolveEndDelta]] description] forKey:MLKEY_DISSOLVEEND]; return dict; } - (id) copyWithZone:(NSZone *)zone { MorphLine *newObject; NSDictionary *dict; dict = [self pList]; newObject = [[[self class] allocWithZone:zone] initWithValuesInDict:dict]; return newObject; } - (void) dealloc { free (startPoints); free (endPoints); [super dealloc]; } - (NSPoint) startPointAtDelta:(float)d { if (d <= moveStartDelta || (moveEndDelta - moveStartDelta < 0.00001)) return startPoints[0]; if (d >= moveEndDelta) return startPoints[1]; return pt_wmean (startPoints[0], startPoints[1], (d - moveStartDelta) / (moveEndDelta - moveStartDelta)); } - (NSPoint) endPointAtDelta:(float)d { if (d <= moveStartDelta || (moveEndDelta - moveStartDelta < 0.00001)) return endPoints[0]; if (d >= moveEndDelta) return endPoints[1]; return pt_wmean (endPoints[0], endPoints[1], (d - moveStartDelta) / (moveEndDelta - moveStartDelta)); } // The following two methods for controlling the coordinates currently // only works when you have only two deltas (0 and 1). This can // be modified to handle any number of points. - (void) setStartPoint:(NSPoint)aPoint atDelta:(float)delta { if (delta < 0.5) startPoints[0] = aPoint; else startPoints[1] = aPoint; } - (void) setEndPoint:(NSPoint)aPoint atDelta:(float)delta { if (delta < 0.5) endPoints[0] = aPoint; else endPoints[1] = aPoint; } /**************************************************************** * Morph Controlls ****************************************************************/ - (void) setMoveStartDelta:(float)a { moveStartDelta = a; moveEndDelta = MAX (moveStartDelta, moveEndDelta); } - (void) setMoveEndDelta:(float)a { moveEndDelta = a; moveStartDelta = MIN (moveStartDelta, moveEndDelta); } - (void) setDissolveStartDelta:(float)a { dissolveStartDelta = a; dissolveEndDelta = MAX (dissolveStartDelta, dissolveEndDelta); } - (void) setDissolveEndDelta:(float)a { dissolveEndDelta = a; dissolveStartDelta = MIN (dissolveStartDelta, dissolveEndDelta); } - (float) moveStartDelta { return moveStartDelta; } - (float) moveEndDelta { return moveEndDelta; } - (float) dissolveStartDelta { return dissolveStartDelta; } - (float) dissolveEndDelta { return dissolveEndDelta; } /**************************************************************** * maths ****************************************************************/ - (NSAffineTransform *) transformFromDelta:(float) beforeDelta toDelta:(float) afterDelta // This method contains bugs that makes unusable. It would be nice to have, so I might fix it some day. // A messy, but working implementation of the transformation mathemathics can be found in Morphed.m { NSPoint s0, s1, e0, e1; // Start and end point coordinates of the lines 0 and 1 NSAffineTransform *t; double scale; t = [NSAffineTransform transform]; s0 = [self startPointAtDelta:beforeDelta]; e0 = [self endPointAtDelta:beforeDelta]; s1 = [self startPointAtDelta:afterDelta]; e1 = [self endPointAtDelta:afterDelta]; scale = pt_dist(e1, s1) / pt_dist(e0, s0); [t translateXBy:-s0.x yBy:-s0.y]; [t rotateByRadians:- line_angle(s0, e0)]; [t scaleXBy:scale yBy:1.0]; [t rotateByRadians:line_angle(s1, e1)]; [t translateXBy:s1.x yBy:s1.y]; return t; } /**************************************************************** * description ****************************************************************/ - (NSString *) description { return [[self pList] description]; } /**************************************************************** * display ****************************************************************/ - (void) drawInView:(NSView *)view delta:(float)delta { NSPoint startPt, endPt; startPt = [self startPointAtDelta:delta]; endPt = [self endPointAtDelta:delta]; PSmoveto (startPt.x, startPt.y); PSlineto (endPt.x, endPt.y); PSstroke(); } - (BOOL) hitTest:(NSPoint) aPoint { return NO; } - (int) hitKnobTest: (NSPoint) aPoint { return NO; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.