RSS

(root)/iphone/common : /source/geometry.h (revision 96)

To get this branch, use:
bzr branch /browse/iphone/common
Line Revision Contents
1 1
//
2
//  geometry.h
3
//
4
//  Created by döme on 26.07.2009.
5
//
6
7 54
/*
8
 * Copyright (c) 2009 Doemoetoer Gulyas.
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions and the following disclaimer.
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in the
18
 *    documentation and/or other materials provided with the distribution.
19
 * 3. The name of the author may not be used to endorse or promote products
20
 *    derived from this software without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
 */
33
34 1
#import <Foundation/Foundation.h>
35
36 5
#import <OpenGLES/ES2/gl.h>
37 51
#import <CoreGraphics/CoreGraphics.h>
38 1
39
typedef union v3
40
{
41
	float a[3];
42
	struct {float x,y,z;} v;
43
} v3;
44
45
typedef union m16
46
{
47
	float a[16];
48
	float m[4][4];
49
} m16;
50
51 4
static inline v3 vcreate(const float a, const float b, const float c)
52
{
53 42
	return (v3){{a,b,c}};
54 4
}
55
56 1
static inline v3 vcross(v3 a, v3 b)
57
{
58 42
	return (v3){{a.v.y*b.v.z-a.v.z*b.v.y, a.v.z*b.v.x - a.v.x*b.v.z, a.v.x*b.v.y - a.v.y*b.v.x}};
59 1
}
60
61
static inline float vdot(v3 a, v3 b)
62
{
63
	return a.v.x*b.v.x+a.v.y*b.v.y+a.v.z*b.v.z;
64
}
65
66
static inline float vlength(v3 a)
67
{
68
	return sqrtf(vdot(a,a));
69
}
70
71
static inline v3 vmul(v3 a, float b)
72
{
73 42
	return (v3){{a.v.x*b, a.v.y*b, a.v.z*b}};
74 1
}
75
76
77
static inline v3 vproject(v3 a, v3 b)
78
{
79
	return vmul(b, vdot(a,b)/vdot(b,b));
80
}
81
82
static inline v3 vnormalize(v3 a)
83
{
84
	float length = vlength(a);
85
	if (length < FLT_EPSILON)
86
		return a;
87
	
88
	a.v.x /= length;
89
	a.v.y /= length;
90
	a.v.z /= length;
91
	
92
	return a;
93
}
94
95
static inline v3 vnegate(v3 a)
96
{
97 42
	return (v3){{-a.v.x,-a.v.y,-a.v.z}};
98 1
}
99
100 2
static inline v3 vadd(const v3 a, const v3 b)
101 1
{
102 42
	return (v3){{a.v.x+b.v.x, a.v.y+b.v.y, a.v.z+b.v.z}};
103 1
}
104
105 2
static inline v3 vsub(const v3 a, const v3 b)
106 1
{
107 42
	return (v3){{a.v.x-b.v.x, a.v.y-b.v.y, a.v.z-b.v.z}};
108 1
}
109
110 33
static inline float vsum(const v3 a)
111
{
112
	return a.v.x+a.v.y+a.v.z;
113
}
114
115
static inline v3 vfloor(const v3 a)
116
{
117 42
	return (v3){{floorf(a.v.x), floorf(a.v.y), floorf(a.v.z)}};
118 33
}
119
120 2
static inline float fclampf(const float a, const float mn, const float mx)
121
{
122
	return fminf(fmaxf(a, mn), mx);
123
}
124
125 25
static inline double fclamp(const double a, const double mn, const double mx)
126
{
127
	return fmin(fmax(a, mn), mx);
128
}
129
130 2
static inline v3 vclamp(const v3 a, const float mn, const float mx)
131
{
132 42
	return (v3){{fclampf(a.v.x,mn,mx), fclampf(a.v.y,mn,mx), fclampf(a.v.z,mn,mx)}};
133 2
}
134
135
136 1
static inline float sign(float a)
137
{
138 42
	return a >= 0.0f ? 1.0f : -1.0f;
139 1
}
140
141 89
static inline float sign3(float a)
142
{
143
	return a > 0.0f ? 1.0f : (a < 0.0f ? -1.0f : 0.0f);
144
}
145
146
147 2
static inline m16 midentity(void)
148
{
149 42
	m16 m = {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}};
150 2
	return m;
151
}
152 1
153 5
static inline m16 mzero(void)
154
{
155 42
	m16 m = {{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}};
156 5
	return m;
157
}
158
159
160 1
static inline m16 mtranspose(const m16 a)
161
{
162
	m16 m;
163
	for (int i = 0; i < 4; ++i)
164
		for (int j = 0; j < 4; ++j)
165
			m.m[i][j] = a.m[j][i];
166
	return m;
167
}
168
169 2
static inline m16 mmul(const m16 a, const m16 b)
170
{
171
	m16 mm;
172
173
	for (int i = 0; i < 4; i++)
174
	{
175
		mm.m[i][0] = b.m[i][0]*a.m[0][0] + b.m[i][1]*a.m[1][0] + b.m[i][2]*a.m[2][0] + b.m[i][3]*a.m[3][0];
176
		mm.m[i][1] = b.m[i][0]*a.m[0][1] + b.m[i][1]*a.m[1][1] + b.m[i][2]*a.m[2][1] + b.m[i][3]*a.m[3][1];
177
		mm.m[i][2] = b.m[i][0]*a.m[0][2] + b.m[i][1]*a.m[1][2] + b.m[i][2]*a.m[2][2] + b.m[i][3]*a.m[3][2];
178
		mm.m[i][3] = b.m[i][0]*a.m[0][3] + b.m[i][1]*a.m[1][3] + b.m[i][2]*a.m[2][3] + b.m[i][3]*a.m[3][3];
179
	}
180
181
	return mm;
182
}
183
184
185 1
static inline v3 mtransformdir3(const m16 a, const v3 b)
186
{
187
	v3 v;
188
	v.v.x = a.a[0]*b.v.x + a.a[4]*b.v.y + a.a[8]*b.v.z;
189
	v.v.y = a.a[1]*b.v.x + a.a[5]*b.v.y + a.a[9]*b.v.z;
190
	v.v.z = a.a[2]*b.v.x + a.a[6]*b.v.y + a.a[10]*b.v.z;
191
	
192
	return v;
193
}
194
195 15
static inline v3 mtransformpos3(const m16 a, const v3 b)
196
{
197
	v3 v;
198
	v.v.x	= a.a[0]*b.v.x + a.a[4]*b.v.y + a.a[8]*b.v.z + a.a[12];
199
	v.v.y	= a.a[1]*b.v.x + a.a[5]*b.v.y + a.a[9]*b.v.z + a.a[13];
200
	v.v.z	= a.a[2]*b.v.x + a.a[6]*b.v.y + a.a[10]*b.v.z + a.a[14];
201
	float w = a.a[3]*b.v.x + a.a[7]*b.v.y + a.a[11]*b.v.z + a.a[15];
202
	return vcreate(v.v.x/w, v.v.y/w, v.v.z/w);
203
}
204
205 89
static inline CGRect mtransformrect(const m16 a, const CGRect b)
206
{
207
	CGRect rr;
208
	rr.origin.x	= a.a[0]*b.origin.x + a.a[4]*b.origin.y + a.a[12];
209
	rr.origin.y	= a.a[1]*b.origin.x + a.a[5]*b.origin.y + a.a[13];
210
	rr.size.width	= a.a[0]*b.size.width + a.a[4]*b.size.height;
211
	rr.size.height	= a.a[1]*b.size.width + a.a[5]*b.size.height;
212
213
	return rr;
214
}
215
216 15
217 1
static inline m16 mcreatefrombases(const v3 ex, const v3 ey, const v3 ez)
218
{	
219 42
	return (m16){{ex.v.x, ex.v.y, ex.v.z, 0.0f,
220
				ey.v.x, ey.v.y, ey.v.z, 0.0f, 
221
				ez.v.x, ez.v.y, ez.v.z, 0.0f,
222
				0.0f, 0.0f, 0.0f, 1.0f}};
223 1
}
224
225 5
static inline m16 madjoint(m16 m)
226
{
227
	float A = m.m[2][2]*m.m[3][3] - m.m[3][2]*m.m[2][3];
228
	float B = m.m[1][2]*m.m[3][3] - m.m[3][2]*m.m[1][3];
229
	float C = m.m[1][2]*m.m[2][3] - m.m[2][2]*m.m[1][3];
230
	float D = m.m[0][2]*m.m[3][3] - m.m[3][2]*m.m[0][3];
231
	float E = m.m[0][2]*m.m[2][3] - m.m[2][2]*m.m[0][3];
232
	float F = m.m[0][2]*m.m[1][3] - m.m[1][2]*m.m[0][3];
233
234
	float A3 = m.m[2][1]*m.m[3][3] - m.m[3][1]*m.m[2][3];
235
	float B3 = m.m[1][1]*m.m[3][3] - m.m[3][1]*m.m[1][3];
236
	float C3 = m.m[1][1]*m.m[2][3] - m.m[2][1]*m.m[1][3];
237
	float D3 = m.m[0][1]*m.m[3][3] - m.m[3][1]*m.m[0][3];
238
	float E3 = m.m[0][1]*m.m[2][3] - m.m[2][1]*m.m[0][3];
239
	float F3 = m.m[0][1]*m.m[1][3] - m.m[1][1]*m.m[0][3];
240
241
	float A4 = m.m[2][1]*m.m[3][2] - m.m[3][1]*m.m[2][2];
242
	float B4 = m.m[1][1]*m.m[3][2] - m.m[3][1]*m.m[1][2];
243
	float C4 = m.m[1][1]*m.m[2][2] - m.m[2][1]*m.m[1][2];
244
	float D4 = m.m[0][1]*m.m[3][2] - m.m[3][1]*m.m[0][2];
245
	float E4 = m.m[0][1]*m.m[2][2] - m.m[2][1]*m.m[0][2];
246
	float F4 = m.m[0][1]*m.m[1][2] - m.m[1][1]*m.m[0][2];
247
248
	float AA = m.m[1][1]*A - m.m[2][1]*B + m.m[3][1]*C;
249
	float BB = m.m[0][1]*A - m.m[2][1]*D + m.m[3][1]*E;
250
	float CC = m.m[0][1]*B - m.m[1][1]*D + m.m[3][1]*F;
251
	float DD = m.m[0][1]*C - m.m[1][1]*E + m.m[2][1]*F;
252
253
	float EE = m.m[1][0]*A - m.m[2][0]*B + m.m[3][0]*C;
254
	float FF = m.m[0][0]*A - m.m[2][0]*D + m.m[3][0]*E;
255
	float GG = m.m[0][0]*B - m.m[1][0]*D + m.m[3][0]*F;
256
	float HH = m.m[0][0]*C - m.m[1][0]*E + m.m[2][0]*F;
257
258
	float II = m.m[1][0]*A3 - m.m[2][0]*B3 + m.m[3][0]*C3;
259
	float JJ = m.m[0][0]*A3 - m.m[2][0]*D3 + m.m[3][0]*E3;
260
	float KK = m.m[0][0]*B3 - m.m[1][0]*D3 + m.m[3][0]*F3;
261
	float LL = m.m[0][0]*C3 - m.m[1][0]*E3 + m.m[2][0]*F3;
262
263
	float MM = m.m[1][0]*A4 - m.m[2][0]*B4 + m.m[3][0]*C4;
264
	float NN = m.m[0][0]*A4 - m.m[2][0]*D4 + m.m[3][0]*E4;
265
	float OO = m.m[0][0]*B4 - m.m[1][0]*D4 + m.m[3][0]*F4;
266
	float PP = m.m[0][0]*C4 - m.m[1][0]*E4 + m.m[2][0]*F4;
267
268
269 42
	return (m16){{AA, -BB, CC, -DD, -EE, FF, -GG, HH, II, -JJ, KK, -LL, -MM, NN, -OO, PP}};
270 5
271
};
272
273
static inline float mdeterminant(m16 m)
274
{
275
	float A = m.m[2][2]*m.m[3][3] - m.m[3][2]*m.m[2][3];
276
	float B = m.m[1][2]*m.m[3][3] - m.m[3][2]*m.m[1][3];
277
	float C = m.m[1][2]*m.m[2][3] - m.m[2][2]*m.m[1][3];
278
	float D = m.m[0][2]*m.m[3][3] - m.m[3][2]*m.m[0][3];
279
	float E = m.m[0][2]*m.m[2][3] - m.m[2][2]*m.m[0][3];
280
	float F = m.m[0][2]*m.m[1][3] - m.m[1][2]*m.m[0][3];
281
282
	float AA = m.m[1][1]*A - m.m[2][1]*B + m.m[3][1]*C;
283
	float BB = m.m[0][1]*A - m.m[2][1]*D + m.m[3][1]*E;
284
	float CC = m.m[0][1]*B - m.m[1][1]*D + m.m[3][1]*F;
285
	float DD = m.m[0][1]*C - m.m[1][1]*E + m.m[2][1]*F;
286
287
	float AAA = m.m[0][0]*AA - m.m[1][0]*BB + m.m[2][0]*CC - m.m[3][0]*DD;
288
289
	return AAA;
290
291
};
292
293
static inline m16 mtranslate(v3 v)
294
{
295
296
	m16 m = midentity();
297
	m.m[3][0] = v.a[0];
298
	m.m[3][1] = v.a[1];
299
	m.m[3][2] = v.a[2];
300
301
	return m;
302
};
303
304
static inline m16 mscale(v3 v)
305
{
306
307
	m16 m = midentity();
308
	m.m[0][0] = v.a[0];
309
	m.m[1][1] = v.a[1];
310
	m.m[2][2] = v.a[2];
311
312
	return m;
313
};
314
315
static inline m16 mperspective(float fovy, float aspect, float zNear, float zFar)
316
{
317
	m16 m = mzero();
318 42
	float f = 1.0f/tanf(fovy*0.5f);
319 5
	
320
	m.m[0][0] = f/aspect;
321
	m.m[1][1] = f;
322
	m.m[2][2] = (zFar+zNear)/(zNear-zFar);
323
	m.m[2][3] = -1;
324 42
	m.m[3][2] = (2.0f*zFar*zNear)/(zNear-zFar);
325 5
326
	return m;
327
}
328
329 7
static inline m16 mortho(float left, float right, float bottom, float top, float zNear, float zFar)
330
{
331
	m16 m = midentity();
332
	
333 42
	m.m[0][0] = 2.0f/(right-left);
334
	m.m[1][1] = 2.0f/(top-bottom);
335
	m.m[2][2] = -2.0f/(zFar-zNear);
336 15
	m.m[3][0] = -(right+left)/(right - left);
337
	m.m[3][1] = -(top + bottom)/(top - bottom);
338 7
	m.m[3][2] = -(zFar + zNear)/(zFar - zNear);
339
340
	return m;
341
}
342
343
344 5
static inline m16 mmuls(m16 m, float s)
345
{
346
	for (int i = 0; i < 16; ++i)
347
		m.a[i] = m.a[i]*s;
348
	return m;
349
}
350
351
static inline m16 minverse(m16 m)
352
{
353
	m16		mm	= madjoint(m);
354
	float	d	= mdeterminant(m);
355 42
    return mmuls(mm, 1.0f/d);
356 5
};
357
358
359 2
m16 computeAlignedBasesFromDownVector(v3 acc);
360 6
m16 computeAlignedBasesFromDownVector2(v3 acc, v3 pf);
361 14
362
#pragma mark CG extensions
363
364 80
static inline CGSize CGSizeScaleDownIntoSize(CGSize a, CGSize b)
365 38
{
366
	CGSize c = a;
367
	float heightR = a.height/b.height;
368
	float widthR = a.width/b.width;
369
	
370
	if (heightR > 1.0f)
371
	{
372
		c.height = b.height;
373
		c.width *= 1.0f/heightR;
374
		widthR = c.width/b.width;
375
	}
376
377
	if (widthR > 1.0f)
378
	{
379
		c.width = b.width;
380
		c.height *= 1.0f/widthR;
381
	}
382
	return c;
383
}
384
385 80
static inline CGSize CGSizeFitToSize(CGSize a, CGSize b)
386
{
387
	float heightR = a.height/b.height;
388
	float widthR = a.width/b.width;
389
	
390
	float minr = fmaxf(heightR,widthR);
391
	
392
	CGSize c = CGSizeMake(a.width*(1.0f/minr), a.height*(1.0f/minr));
393
	
394
	return c;
395
}
396
397 87
static inline CGSize CGSizeFloor(CGSize a)
398
{
399
	CGSize c = CGSizeMake(floorf(a.width), floorf(a.height));
400
	
401
	return c;
402
}
403
404 38
405 74
static inline CGPoint CGPointMin(CGPoint a, CGPoint b)
406
{
407
	return CGPointMake(fminf(a.x,b.x), fminf(a.y,b.y));
408
}
409
410
static inline CGPoint CGPointMax(CGPoint a, CGPoint b)
411
{
412
	return CGPointMake(fmaxf(a.x,b.x), fmaxf(a.y,b.y));
413
}
414
415 14
static inline CGPoint CGPointAdd(CGPoint a, CGPoint b)
416
{
417
	return CGPointMake(a.x+b.x, a.y+b.y);
418
}
419
420
static inline CGPoint CGPointSub(CGPoint a, CGPoint b)
421
{
422
	return CGPointMake(a.x-b.x, a.y-b.y);
423
}
424
425
static inline CGPoint CGPointScale(CGPoint a, float b)
426
{
427
	return CGPointMake(a.x*b, a.y*b);
428
}
429
430 66
static inline CGSize CGSizeScale(CGSize a, float b)
431
{
432
	return CGSizeMake(a.width*b, a.height*b);
433
}
434
435 14
static inline float CGPointDoubleDot(CGPoint a)
436
{
437
	return a.x*a.x+a.y*a.y;
438
}
439
440
static inline float CGPointDot(CGPoint a, CGPoint b)
441
{
442
	return (a.x*b.x + a.y*b.y);
443
}
444
445
static inline float CGPointCross(CGPoint a, CGPoint b)
446
{
447
	return (a.x*b.y - a.y*b.x);
448
}
449
450 17
static inline CGPoint CGPointNormalize(CGPoint a)
451
{
452
	float l1 = 1.0f/sqrtf(a.x*a.x+a.y*a.y);
453
	return CGPointMake(a.x*l1, a.y*l1);
454
}
455
456 24
static inline CGPoint CGPointNegate(CGPoint a)
457
{
458
	return CGPointMake(-a.x, -a.y);
459
}
460
461 38
static inline CGPoint CGPointNormal(CGPoint a)
462
{
463
	return CGPointMake(-a.y, a.x);
464
}
465
466 24
static inline float CGPointLength(CGPoint a)
467
{
468
	return sqrtf(a.x*a.x+a.y*a.y);
469
}
470
471 17
static inline CGPoint CGPointProject(CGPoint a, CGPoint b)
472
{
473
	return CGPointScale(b, CGPointDot(a,b)/CGPointDot(b,b));
474
}
475
476
static inline CGPoint CGPointReverseProject(CGPoint a, CGPoint b)
477
{
478
	return CGPointScale(b, CGPointDot(a,a)/CGPointDot(a,b));
479
}
480
481 66
static inline CGPoint CGPointLerp(CGPoint a, CGPoint b, float t)
482
{
483
	return CGPointAdd(a, CGPointScale(CGPointSub(b, a), t));
484
}
485
486
487
static inline CGPoint CGPointRotate(CGPoint a, float w)
488
{
489
	float cosa = cosf(w), sina = sin(w);
490
	
491
	CGPoint r;
492
493 74
	r.x = a.x*cosa - a.y*sina;
494
	r.y = a.y*cosa + a.x*sina;
495 66
496
	return r;
497
	
498
}
499
500 84
static inline CGRect CGRectLerp(CGRect a, CGRect b, CGFloat t)
501
{
502
	CGFloat t1 = 1.0 - t;
503
	return CGRectMake(a.origin.x*t1 + b.origin.x*t, a.origin.y*t1 + b.origin.y*t, a.size.width*t1 + b.size.width*t, a.size.height*t1 + b.size.height*t);
504
}
505
506 17
507 14
static inline long CGLineSegmentsIntersect2(CGPoint p0, CGPoint p1, CGPoint p2, CGPoint p3)
508
{
509
	float d = (p3.y - p2.y)*(p1.x - p0.x) - (p3.x - p2.x)*(p1.y - p0.y);
510
	
511
	if (d == 0.0)
512
		return 0;
513
	
514
	float a = (p3.x - p2.x)*(p0.y - p2.y) + (p3.y - p2.y)*(p0.x - p2.x);
515
	float b = (p1.x - p0.x)*(p0.y - p2.y) + (p1.y - p0.y)*(p0.x - p2.x);
516
	
517
	float ta = a/d;
518
	float tb = b/d;
519
520
	return ((ta > 0.0) && (ta < 1.0) && (tb > 0.0) && (tb < 1.0));
521
}
522
523
static inline long CGLineSegmentsIntersect(CGPoint p0, CGPoint p1, CGPoint p2, CGPoint p3)
524
{
525
	float d = CGPointCross(CGPointSub(p1,p0), CGPointSub(p3,p2));
526
	
527
	if (d == 0.0)
528
		return 0;
529
	
530
	float a = CGPointCross(CGPointSub(p2,p0), CGPointSub(p3,p2));
531
	float b = CGPointCross(CGPointSub(p2,p0), CGPointSub(p1,p0));
532
	
533
	float ta = a/d;
534
	float tb = b/d;
535
536
	return ((ta > 0.0) && (ta < 1.0) && (tb > 0.0) && (tb < 1.0));
537
}
538
539 23
static inline CGPoint CGLineIntersectionPoint(CGPoint p0, CGPoint p1, CGPoint p2, CGPoint p3)
540
{
541
	float d = CGPointCross(CGPointSub(p1,p0), CGPointSub(p3,p2));
542
	
543
	if (d == 0.0)
544
		return CGPointZero;
545
	
546
//	float a = CGPointCross(CGPointSub(p2,p0), CGPointSub(p3,p2));
547
	float b = CGPointCross(CGPointSub(p2,p0), CGPointSub(p1,p0));
548
	
549
//	float ta = a/d;
550
	float tb = b/d;
551
552
	return CGPointAdd(p2, CGPointScale(CGPointSub(p3,p2), tb));
553
}
554
555
556 16
static inline long CGPointInTriangle(CGPoint p, CGPoint a0, CGPoint a1, CGPoint a2)
557
{
558
	CGPoint v0 = CGPointSub(a1, a0);
559
	CGPoint v1 = CGPointSub(a2, a0);
560
	CGPoint v2 = CGPointSub(p, a0);
561
562
	float dot00 = CGPointDot(v0, v0);
563
	float dot01 = CGPointDot(v0, v1);
564
	float dot02 = CGPointDot(v0, v2);
565
	float dot11 = CGPointDot(v1, v1);
566
	float dot12 = CGPointDot(v1, v2);
567
568 42
	float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
569 16
	float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
570
	float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
571
572
	return (u > 0) && (v > 0) && (u + v < 1.0);
573
574
}
575 14
576 17
static long CGPointInCircumCircule(CGPoint d, CGPoint a, CGPoint b, CGPoint c)
577
{
578
	float m[3][3] = {
579
		{ a.x-d.x, b.x-d.x, c.x-d.x },
580
		{ a.y-d.y, b.y-d.y, c.y-d.y },
581
		{ CGPointDoubleDot(a) - CGPointDoubleDot(d), CGPointDoubleDot(b) - CGPointDoubleDot(d), CGPointDoubleDot(a) - CGPointDoubleDot(c), }
582
	};
583
	
584
	float cof[3] = {
585
		m[1][1]*m[2][2] -  m[2][1]*m[1][2],
586
		m[0][1]*m[2][2] -  m[2][1]*m[0][2],
587
		m[0][1]*m[1][2] -  m[1][1]*m[0][2]
588
	};
589
	float det = m[0][0]*cof[0] - m[1][0]*cof[1] + m[2][0]*cof[2];
590
	
591
	return det > 0;
592
}
593
594
595
596 14
static inline CGPoint cubicPointAtT(CGPoint p0, CGPoint p1, CGPoint p2, CGPoint p3, float t)
597
{
598 42
	float t1 = 1.0f-t;
599 14
	CGPoint p01 = CGPointAdd(CGPointScale(p0, t1), CGPointScale(p1, t));
600
	CGPoint p12 = CGPointAdd(CGPointScale(p1, t1), CGPointScale(p2, t));
601
	CGPoint p23 = CGPointAdd(CGPointScale(p2, t1), CGPointScale(p3, t));
602
	CGPoint p02 = CGPointAdd(CGPointScale(p01, t1), CGPointScale(p12, t));
603
	CGPoint p13 = CGPointAdd(CGPointScale(p12, t1), CGPointScale(p23, t));
604
	CGPoint p03 = CGPointAdd(CGPointScale(p02, t1), CGPointScale(p13, t));
605
	return p03;
606
}
607
608
static inline CGPoint quadraticPointAtT(CGPoint p0, CGPoint p1, CGPoint p2, float t)
609
{
610 42
	float t1 = 1.0f-t;
611 14
	CGPoint p01 = CGPointAdd(CGPointScale(p0, t1), CGPointScale(p1, t));
612
	CGPoint p12 = CGPointAdd(CGPointScale(p1, t1), CGPointScale(p2, t));
613
	CGPoint p02 = CGPointAdd(CGPointScale(p01, t1), CGPointScale(p12, t));
614
	return p02;
615
}
616
617
static inline CGPoint linearPointAtT(CGPoint p0, CGPoint p1, float t)
618
{
619 42
	float t1 = 1.0f-t;
620 14
	CGPoint p01 = CGPointAdd(CGPointScale(p0, t1), CGPointScale(p1, t));
621
	return p01;
622
}
623
624 15
CGPathRef CreateTransformedPathFromCGPath(CGPathRef cpath, CGAffineTransform m);
625
626
CGPoint CGPointTransform(CGPoint a, CGAffineTransform m);

Loggerhead 1.17 is a web-based interface for Bazaar branches