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.