Created
February 2, 2010 03:22
-
-
Save jon/292330 to your computer and use it in GitHub Desktop.
A collection of 2D vector-geometry functions for dealing with CGPoints in Cocoa/Cocoa Touch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* BPGeometry.h | |
* | |
* Created by Jon Olson on 11/30/09. | |
* Copyright 2009 Ballistic Pigeon, LLC. All rights reserved. | |
* | |
*/ | |
#import <Foundation/Foundation.h> | |
extern CGPoint CGPointScale(CGPoint A, double b); | |
extern CGPoint CGPointAdd(CGPoint a, CGPoint b); | |
extern CGPoint CGPointSubtract(CGPoint a, CGPoint b); | |
extern double CGPointCross(CGPoint a, CGPoint b); | |
extern double CGPointDot(CGPoint a, CGPoint b); | |
extern double CGPointMagnitude(CGPoint pt); | |
extern CGPoint CGPointNormalize(CGPoint pt); | |
extern BOOL BPLineSegmentsIntersect(CGPoint a1, CGPoint a2, CGPoint b1, CGPoint b2); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* BPGeometry.m | |
* | |
* Created by Jon Olson on 11/30/09. | |
* Copyright 2009 Ballistic Pigeon, LLC. All rights reserved. | |
* | |
*/ | |
#include "BPGeometry.h" | |
/** | |
* Calculate the vector-scalar product A*b | |
*/ | |
CGPoint CGPointScale(CGPoint A, double b) { | |
return CGPointMake(A.x*b, A.y*b); | |
} | |
/** | |
* Calculate the vector-vector sum a+b | |
*/ | |
CGPoint CGPointAdd(CGPoint a, CGPoint b) { | |
return CGPointMake(a.x + b.x, a.y + b.y); | |
} | |
/** | |
* Calculate the vector-vector difference a-b | |
*/ | |
CGPoint CGPointSubtract(CGPoint a, CGPoint b) { | |
return CGPointMake(a.x - b.x, a.y - b.y); | |
} | |
/** | |
* Calculate the cross product for two 2D vectors by treating them as 3D | |
* vectors with zero for the third component. As the direction of the | |
* resulting vector is always directly up the z-axis, this returns a scalar | |
* equal to |a|*|b|*sin(alpha) where alpha is the angle in the plane between | |
* a and b. | |
*/ | |
double CGPointCross(CGPoint a, CGPoint b) { | |
return a.x*b.y - b.x*a.y; | |
} | |
/** | |
* Calculate the dot-product of two 2D vectors a dot b | |
*/ | |
double CGPointDot(CGPoint a, CGPoint b) { | |
return a.x*b.x + a.y*b.y; | |
} | |
/** | |
* Calculate the magnitude of a 2D vector | |
*/ | |
double CGPointMagnitude(CGPoint pt) { | |
return sqrt(CGPointDot(pt, pt)); | |
} | |
/** | |
* Normalize a 2D vector | |
*/ | |
CGPoint CGPointNormalize(CGPoint pt) { | |
return CGPointScale(pt, 1.0 / CGPointMagnitude(pt)); | |
} | |
/** | |
* Determining whether two line segments intersect is harder than you'd think. | |
* | |
* There is an obvious way to do it, but it requires many special cases and doesn't look pretty. | |
*/ | |
// From http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect/565282#565282 | |
BOOL BPLineSegmentsIntersect(CGPoint a1, CGPoint a2, CGPoint b1, CGPoint b2) { | |
if (CGPointEqualToPoint(a1, a2)) | |
return NO; | |
if (CGPointEqualToPoint(b1, b2)) | |
return NO; | |
CGPoint r = CGPointSubtract(a2, a1); | |
CGPoint s = CGPointSubtract(b2, b1); | |
double cross = CGPointCross(r, s); | |
if (cross == 0.0) | |
return NO; | |
CGPoint v = CGPointSubtract(b1, a1); | |
double t = CGPointCross(v, s) / cross; | |
double u = CGPointCross(v, r) / cross; | |
BOOL intersect = (0.0 <= t) && (t <= 1.0) && (0.0 <= u) && (u <= 1.0); | |
if (intersect) | |
DebugLog(@"intersect:%@ (cross:%f t:%f u:%f)", NSStringFromCGPoint(CGPointAdd(a1, CGPointScale(CGPointSubtract(a2, a1), t))), cross, t, u); | |
return intersect; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Do you have a current version for Xcode 7.1? iOS 8