home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / Rhapsody / Graphics / Morph-2.0a / MorphLine.m < prev    next >
Encoding:
Text File  |  1998-01-25  |  7.2 KB  |  264 lines

  1. // MorphLine.m
  2. //
  3. // created by Martin Wennerberg on Sun 12-Nov-1995
  4. //
  5. // when        who    modification
  6.  
  7. #import "MorphLine.h"
  8. #import "algebra.h"
  9.  
  10. @implementation MorphLine
  11.  
  12. - init
  13. {
  14.     self = [super init];
  15.     nPoints = 2;
  16.     startPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint));
  17.     endPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint));
  18.     moveStartDelta     = 0.0;
  19.     moveEndDelta       = 1.0;
  20.     dissolveStartDelta = 0.0;
  21.     dissolveEndDelta   = 1.0;
  22.  
  23.     return self;
  24. }
  25.  
  26. - initWithValuesInDict:(NSDictionary *)dict
  27. {
  28.     NSArray    *startPointsValues;
  29.     NSArray    *endPointsValues;
  30.     NSNumber    *number;
  31.  
  32.     self = [self init];
  33.     if ([dict isKindOfClass:[NSString class]])
  34.         dict = [(NSString *)dict propertyList];
  35.  
  36.     startPointsValues = [dict objectForKey:MLKEY_STARTPOINTS];
  37.     endPointsValues = [dict objectForKey:MLKEY_ENDPOINTS];
  38.     if (MIN([startPointsValues count], [endPointsValues count]) >= 2)
  39.       {
  40.         unsigned     i;
  41.  
  42.         nPoints = MIN([startPointsValues count], [endPointsValues count]);
  43.         free (startPoints);
  44.         free (endPoints);
  45.         startPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint));
  46.         endPoints = NSZoneCalloc([self zone], nPoints, sizeof(NSPoint));
  47.         for (i = 0; i < nPoints; ++i)
  48.           {
  49.             startPoints[i] = NSPointFromString([startPointsValues objectAtIndex:i]);
  50.             endPoints[i] = NSPointFromString([endPointsValues objectAtIndex:i]);
  51.           }
  52.       }
  53.     number = [dict objectForKey:MLKEY_MOVESTART];
  54.     if (number != nil)
  55.         [self setMoveStartDelta:[number floatValue]];
  56.  
  57.     number = [dict objectForKey:MLKEY_MOVEEND];
  58.     if (number != nil)
  59.         [self setMoveEndDelta:[number floatValue]];
  60.  
  61.     number = [dict objectForKey:MLKEY_DISSOLVESTART];
  62.     if (number != nil)
  63.         [self setDissolveStartDelta:[number floatValue]];
  64.  
  65.     number = [dict objectForKey:MLKEY_DISSOLVEEND];
  66.     if (number != nil)
  67.         [self setDissolveEndDelta:[number floatValue]];
  68.  
  69.     return self;
  70. }
  71.  
  72. - (NSDictionary *)pList
  73. {
  74.     NSMutableDictionary    *dict;
  75.     NSMutableArray    *startPointStrings;
  76.     NSMutableArray    *endPointStrings;
  77.     unsigned         i;
  78.  
  79.     dict = [NSMutableDictionary dictionaryWithCapacity:10];
  80.     startPointStrings = [NSMutableArray arrayWithCapacity:nPoints];
  81.     endPointStrings = [NSMutableArray arrayWithCapacity:nPoints];
  82.  
  83.     for (i = 0; i < nPoints; ++i)
  84.       {
  85.         [startPointStrings addObject:NSStringFromPoint(startPoints[i])];
  86.         [endPointStrings addObject:NSStringFromPoint(endPoints[i])];
  87.       }
  88.  
  89.     [dict setObject:startPointStrings forKey:MLKEY_STARTPOINTS];
  90.     [dict setObject:endPointStrings forKey:MLKEY_ENDPOINTS];
  91.     [dict setObject:[[NSNumber numberWithFloat:[self moveStartDelta]] description] forKey:MLKEY_MOVESTART];
  92.     [dict setObject:[[NSNumber numberWithFloat:[self moveEndDelta]] description] forKey:MLKEY_MOVEEND];
  93.     [dict setObject:[[NSNumber numberWithFloat:[self dissolveStartDelta]] description] forKey:MLKEY_DISSOLVESTART];
  94.     [dict setObject:[[NSNumber numberWithFloat:[self dissolveEndDelta]] description] forKey:MLKEY_DISSOLVEEND];
  95.  
  96.     return dict;
  97. }
  98.  
  99. - (id) copyWithZone:(NSZone *)zone
  100. {
  101.     MorphLine        *newObject;
  102.     NSDictionary    *dict;
  103.  
  104.     dict = [self pList];
  105.     newObject = [[[self class] allocWithZone:zone] initWithValuesInDict:dict];
  106.     return newObject;
  107. }
  108.  
  109. - (void) dealloc
  110. {
  111.     free (startPoints);
  112.     free (endPoints);
  113.     [super dealloc];
  114. }
  115.  
  116. - (NSPoint) startPointAtDelta:(float)d
  117. {
  118.     if (d <= moveStartDelta || (moveEndDelta - moveStartDelta < 0.00001))
  119.         return startPoints[0];
  120.     if (d >= moveEndDelta)
  121.         return startPoints[1];
  122.     return pt_wmean (startPoints[0], startPoints[1], (d - moveStartDelta) / (moveEndDelta - moveStartDelta));
  123. }
  124.  
  125. - (NSPoint) endPointAtDelta:(float)d
  126. {
  127.     if (d <= moveStartDelta || (moveEndDelta - moveStartDelta < 0.00001))
  128.         return endPoints[0];
  129.     if (d >= moveEndDelta)
  130.         return endPoints[1];
  131.     return pt_wmean (endPoints[0], endPoints[1], (d - moveStartDelta) / (moveEndDelta - moveStartDelta));
  132. }
  133.  
  134. // The following two methods for controlling the coordinates currently
  135. // only works when you have only two deltas (0 and 1). This can
  136. // be modified to handle any number of points.
  137. - (void) setStartPoint:(NSPoint)aPoint atDelta:(float)delta
  138. {
  139.     if (delta < 0.5)
  140.         startPoints[0] = aPoint;
  141.     else
  142.         startPoints[1] = aPoint;
  143. }
  144.  
  145. - (void) setEndPoint:(NSPoint)aPoint atDelta:(float)delta
  146. {
  147.     if (delta < 0.5)
  148.         endPoints[0] = aPoint;
  149.     else
  150.         endPoints[1] = aPoint;
  151. }
  152.  
  153.  
  154. /****************************************************************
  155. * Morph Controlls
  156. ****************************************************************/
  157.  
  158. - (void) setMoveStartDelta:(float)a
  159. {
  160.     moveStartDelta = a;
  161.     moveEndDelta = MAX (moveStartDelta, moveEndDelta);
  162. }
  163.  
  164. - (void) setMoveEndDelta:(float)a
  165. {
  166.     moveEndDelta = a;
  167.     moveStartDelta = MIN (moveStartDelta, moveEndDelta);
  168. }
  169.  
  170. - (void) setDissolveStartDelta:(float)a
  171. {
  172.     dissolveStartDelta = a;
  173.     dissolveEndDelta = MAX (dissolveStartDelta, dissolveEndDelta);
  174. }
  175.  
  176. - (void) setDissolveEndDelta:(float)a
  177. {
  178.     dissolveEndDelta = a;
  179.     dissolveStartDelta = MIN (dissolveStartDelta, dissolveEndDelta);
  180. }
  181.  
  182. - (float) moveStartDelta
  183. {
  184.     return moveStartDelta;
  185. }
  186.  
  187. - (float) moveEndDelta
  188. {
  189.     return moveEndDelta;
  190. }
  191.  
  192. - (float) dissolveStartDelta
  193. {
  194.     return dissolveStartDelta;
  195. }
  196.  
  197. - (float) dissolveEndDelta
  198. {
  199.     return dissolveEndDelta;
  200. }
  201.  
  202. /****************************************************************
  203. * maths                                                
  204. ****************************************************************/
  205. - (NSAffineTransform *) transformFromDelta:(float) beforeDelta
  206.                                    toDelta:(float) afterDelta
  207. // This method contains bugs that makes unusable. It would be nice to have, so I might fix it some day.
  208. // A messy, but working implementation of the transformation mathemathics can be found in Morphed.m
  209. {
  210.     NSPoint    s0, s1, e0, e1;        // Start and end point coordinates of the lines 0 and 1
  211.     NSAffineTransform    *t;
  212.     double                scale;
  213.  
  214.     t = [NSAffineTransform transform];
  215.     
  216.     s0 = [self startPointAtDelta:beforeDelta];
  217.     e0 = [self endPointAtDelta:beforeDelta];
  218.     s1 = [self startPointAtDelta:afterDelta];
  219.     e1 = [self endPointAtDelta:afterDelta];
  220.  
  221.     scale  = pt_dist(e1, s1) / pt_dist(e0, s0);
  222.     
  223.     [t translateXBy:-s0.x yBy:-s0.y];
  224.     [t rotateByRadians:- line_angle(s0, e0)];
  225.     [t scaleXBy:scale yBy:1.0];
  226.     [t rotateByRadians:line_angle(s1, e1)];
  227.     [t translateXBy:s1.x yBy:s1.y];
  228.         
  229.     return t;
  230. }
  231.  
  232. /****************************************************************
  233. * description                                                
  234. ****************************************************************/
  235. - (NSString *) description
  236. {
  237.     return [[self pList] description];
  238. }
  239.  
  240. /****************************************************************
  241. * display
  242. ****************************************************************/
  243. - (void) drawInView:(NSView *)view delta:(float)delta
  244. {
  245.     NSPoint    startPt, endPt;
  246.  
  247.     startPt = [self startPointAtDelta:delta];
  248.     endPt = [self endPointAtDelta:delta];
  249.     PSmoveto (startPt.x, startPt.y);
  250.     PSlineto (endPt.x, endPt.y);
  251.     PSstroke();
  252. }
  253.  
  254. - (BOOL) hitTest:(NSPoint) aPoint
  255. {
  256.     return NO;
  257. }
  258. - (int) hitKnobTest: (NSPoint) aPoint
  259. {
  260.     return NO;
  261. }
  262.  
  263. @end
  264.