-
Notifications
You must be signed in to change notification settings - Fork 0
/
Particle.m
113 lines (96 loc) · 3.62 KB
/
Particle.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//
// Particle.m
// ModeMaker
//
// Created by David Hirsch on 9/21/09.
// Copyright 2009 Western Washington University. All rights reserved.
//
#import "Particle.h"
#import "constants.h"
@implementation Particle
- (id) initWithBoundsRect: (NSRect) boundsRect
size: (float) inSize
sizeSD: (float) inSizeSD
aspectRatio: (float) inAspectRatio
aspectRatioSD: (float) inAspectRatioSD
complexity: (short) inComplexity
complexitySD: (float) inComplexitySD
fabricStrength: (float) inFabricStrength
allowReentrants: (BOOL) inAllowReentrants;
{
self = [super init];
// initialize with random location within Bounds Rect - this rect should be expanded from the canvas specified in the UI to avoid edge effects
float randX = (boundsRect.size.width * (float) rand() / (float) RAND_MAX) + boundsRect.origin.x;
float randY = (boundsRect.size.height * (float) rand() / (float) RAND_MAX) + boundsRect.origin.y;
center = NSMakePoint(randX, randY);
float normalSizeValue = [self normalValueWithMean: inSize standardDev: inSizeSD]; // this is not the area, but sqrt(area)
area = (kSmallestParticleArea < normalSizeValue) ? (normalSizeValue * normalSizeValue) : kSmallestParticleArea;
myPath = [NSBezierPath bezierPath ]; // create a new path - will be filled in by inheritor class
[myPath retain];
return self;
}
- (void) dealloc {
[myPath release];
[super dealloc];
}
- (void) draw {
[myPath fill];
/* For Debugging:
[[NSColor greenColor] setStroke];
[myPath stroke];
[NSBezierPath fillRect:NSMakeRect(center.x-2, center.y-2, 4, 4)];
*/
}
- (void) adjustAreaByFactor: (float) areaFactor {
area *= areaFactor;
float scaleFactor = sqrt(areaFactor);
NSAffineTransform *transform = [NSAffineTransform transform];
// need to translate the path to the origin, then shrink/expand it, then translate it back. Otherwise, expanding the COORDINATE SYSTEM
// will cause the path to move, I think
[transform translateXBy: -center.x yBy:-center.y];
[transform scaleXBy:scaleFactor yBy:scaleFactor];
[myPath transformUsingAffineTransform: transform];
transform = [NSAffineTransform transform]; // get a new empty transform; avoids worrying about combinatory surprises
[transform translateXBy: center.x yBy:center.y];
[myPath transformUsingAffineTransform: transform];
}
- (void) adaptToSize {
NSLog(@"Particle is Abstract - flow should not have arrived here.");
}
- (float) normalValueWithMean: (float) inMean
standardDev:(float) inSD
{
float U1 = (float) rand() / (float) RAND_MAX;
float U2 = (float) rand() / (float) RAND_MAX;
float z1 = sqrt(-2 * log(U1)) * sin(2 * pi * U2);
return (inMean + z1 * inSD);
}
- (BOOL) containsPoint: (NSPoint) inPoint {
return [myPath containsPoint:inPoint];
}
- (BOOL) overlapsWith: (Particle *) inOtherParticle {
NSLog (@"Particle is Abstract - flow should not have arrived here.");
return YES;
}
- (NSPoint) center {return center;}
- (void) setCenter: (NSPoint)input {center = input;}
- (NSBezierPath *) path {return myPath;}
#define centerX_key @"centerX"
#define centerY_key @"centerY"
#define area_key @"area"
#define myPath_key @"myPath"
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeFloat:center.x forKey:centerX_key];
[coder encodeFloat:center.y forKey:centerY_key];
[coder encodeFloat:area forKey:area_key];
[coder encodeObject:myPath forKey:myPath_key];
}
- (id)initWithCoder:(NSCoder *)decoder {
//self = [super initWithCoder:decoder];
center.x = [decoder decodeFloatForKey:centerX_key];
center.y = [decoder decodeFloatForKey:centerY_key];
area = [decoder decodeFloatForKey:area_key];
myPath = [[decoder decodeObjectForKey:myPath_key] retain];
return self;
}
@end