1 // Copyright 2013 Howling Moon Software. All rights reserved.
2 // See http://chipmunk2d.net/legal.php for more information.
4 #import <malloc/malloc.h>
6 #import "ChipmunkAutoGeometry.h"
8 @implementation ChipmunkPolyline
10 -(id)initWithPolyline:(cpPolyline *)line
12 if((self = [super init])){
21 cpPolylineFree(_line);
26 +(ChipmunkPolyline *)fromPolyline:(cpPolyline *)line
28 return [[[self alloc] initWithPolyline:line] autorelease];
33 return cpPolylineIsClosed(_line);
38 if(_area == 0.0 && [self isClosed]){
39 _area = cpAreaForPoly(_line->count - 1, _line->verts, 0.0);
47 cpAssertHard([self isClosed], "Cannot compute the centroid of a non-looped polyline.");
48 return cpCentroidForPoly(_line->count - 1, _line->verts);
51 -(cpFloat)momentForMass:(cpFloat)mass offset:(cpVect)offset
53 cpAssertHard([self isClosed], "Cannot compute the moment of a non-looped polyline.");
54 return cpMomentForPoly(mass, _line->count - 1, _line->verts, offset, 0.0);
57 -(NSUInteger)count {return _line->count;}
58 -(const cpVect *)verts {return _line->verts;}
60 -(ChipmunkPolyline *)simplifyCurves:(cpFloat)tolerance
62 return [ChipmunkPolyline fromPolyline:cpPolylineSimplifyCurves(_line, tolerance)];
65 -(ChipmunkPolyline *)simplifyVertexes:(cpFloat)tolerance
67 return [ChipmunkPolyline fromPolyline:cpPolylineSimplifyVertexes(_line, tolerance)];
70 -(ChipmunkPolyline *)toConvexHull:(cpFloat)tolerance
72 return [ChipmunkPolyline fromPolyline:cpPolylineToConvexHull(_line, tolerance)];
75 -(ChipmunkPolyline *)toConvexHull
77 return [self toConvexHull:0.0];
80 -(ChipmunkPolylineSet *)toConvexHulls_BETA:(cpFloat)tolerance
82 cpPolylineSet *set = cpPolylineConvexDecomposition_BETA(_line, tolerance);
83 ChipmunkPolylineSet *value = [ChipmunkPolylineSet fromPolylineSet:set];
84 cpPolylineSetFree(set, FALSE);
89 -(NSArray *)asChipmunkSegmentsWithBody:(ChipmunkBody *)body radius:(cpFloat)radius offset:(cpVect)offset
91 NSMutableArray *arr = [NSMutableArray arrayWithCapacity:_line->count];
94 cpVect a = cpvadd(_line->verts[0], offset);
95 for(int i=1; i<_line->count; i++){
96 cpVect b = cpvadd(_line->verts[i], offset);
97 [arr addObject:[ChipmunkSegmentShape segmentWithBody:body from:a to:b radius:radius]];
104 -(ChipmunkPolyShape *)asChipmunkPolyShapeWithBody:(ChipmunkBody *)body transform:(cpTransform)transform radius:(cpFloat)radius
106 cpAssertHard([self isClosed], "Cannot create a poly shape for a non-closed polyline.");
107 return [ChipmunkPolyShape polyWithBody:body count:_line->count - 1 verts:_line->verts transform:transform radius:radius];
114 @implementation ChipmunkPolylineSet
116 -(id)initWithPolylineSet:(cpPolylineSet *)set
118 if((self = [super init])){
119 _lines = [[NSMutableArray alloc] initWithCapacity:set->count];
120 for(int i=0; i<set->count; i++) [_lines addObject:[ChipmunkPolyline fromPolyline:set->lines[i]]];
133 +(ChipmunkPolylineSet *)fromPolylineSet:(cpPolylineSet *)set
135 return [[[self alloc] initWithPolylineSet:set] autorelease];
138 -(NSUInteger)count {return _lines.count;}
140 -(ChipmunkPolyline *)lineAtIndex:(NSUInteger)index
142 return [_lines objectAtIndex:index];
145 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
147 return [_lines countByEnumeratingWithState:state objects:stackbuf count:len];
154 @implementation ChipmunkAbstractSampler
156 @synthesize marchThreshold = _marchThreshold;
157 @synthesize sampleFunc = _sampleFunc;
161 exceptionWithName:NSInternalInconsistencyException
162 reason:[NSString stringWithFormat:@"Use designated initializer initWithSamplingFunction: to initialize a sampler."]
167 -(id)initWithSamplingFunction:(cpMarchSampleFunc)sampleFunc
169 if((self = [super init])){
170 _sampleFunc = sampleFunc;
171 _marchThreshold = 0.5;
177 -(cpFloat)sample:(cpVect)pos
179 return _sampleFunc(pos, self);
183 -(ChipmunkPolylineSet *)march:(cpBB)bb xSamples:(NSUInteger)xSamples ySamples:(NSUInteger)ySamples hard:(bool)hard
186 cpPolylineSetInit(&set);
188 (hard ? cpMarchHard : cpMarchSoft)(
189 bb, xSamples, ySamples, _marchThreshold,
190 (cpMarchSegmentFunc)cpPolylineSetCollectSegment, &set,
194 ChipmunkPolylineSet *value = [ChipmunkPolylineSet fromPolylineSet:&set];
196 cpPolylineSetDestroy(&set, FALSE);
204 @implementation ChipmunkBlockSampler
207 SampleFromBlock(cpVect point, ChipmunkBlockSampler *self)
209 return self->_block(point);
212 -(id)initWithBlock:(ChipmunkMarchSampleBlock)block
214 if((self = [super initWithSamplingFunction:(cpMarchSampleFunc)SampleFromBlock])){
215 _block = [block copy];
221 +(ChipmunkBlockSampler *)samplerWithBlock:(ChipmunkMarchSampleBlock)block
223 return [[[self alloc] initWithBlock:block] autorelease];