-
Notifications
You must be signed in to change notification settings - Fork 471
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from ruslanskorb/develop
Version bump (1.1.0)
- Loading branch information
Showing
10 changed files
with
655 additions
and
85 deletions.
There are no files selected for viewing
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// | ||
// CGGeometry+RSKImageCropper.h | ||
// | ||
// Copyright (c) 2015 Ruslan Skorb, http://ruslanskorb.com/ | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
// THE SOFTWARE. | ||
// | ||
|
||
#import <CoreGraphics/CoreGraphics.h> | ||
#import <tgmath.h> | ||
|
||
// tgmath functions aren't used on iOS when modules are enabled. | ||
// Open Radar - http://www.openradar.me/16744288 | ||
// Work around this by redeclaring things here. | ||
|
||
#undef cos | ||
#define cos(__x) __tg_cos(__tg_promote1((__x))(__x)) | ||
|
||
#undef sin | ||
#define sin(__x) __tg_sin(__tg_promote1((__x))(__x)) | ||
|
||
#undef atan2 | ||
#define atan2(__x, __y) __tg_atan2(__tg_promote2((__x), (__y))(__x), \ | ||
__tg_promote2((__x), (__y))(__y)) | ||
|
||
#undef pow | ||
#define pow(__x, __y) __tg_pow(__tg_promote2((__x), (__y))(__x), \ | ||
__tg_promote2((__x), (__y))(__y)) | ||
|
||
#undef sqrt | ||
#define sqrt(__x) __tg_sqrt(__tg_promote1((__x))(__x)) | ||
|
||
#undef fabs | ||
#define fabs(__x) __tg_fabs(__tg_promote1((__x))(__x)) | ||
|
||
#ifdef CGFLOAT_IS_DOUBLE | ||
#define RSK_EPSILON DBL_EPSILON | ||
#else | ||
#define RSK_EPSILON FLT_EPSILON | ||
#endif | ||
|
||
// Line segments. | ||
struct RSKLineSegment { | ||
CGPoint start; | ||
CGPoint end; | ||
}; | ||
typedef struct RSKLineSegment RSKLineSegment; | ||
|
||
// The "empty" point. This is the point returned when, for example, we | ||
// intersect two disjoint line segments. Note that the null point is not the | ||
// same as the zero point. | ||
CG_EXTERN const CGPoint RSKPointNull; | ||
|
||
// Returns the exact center point of the given rectangle. | ||
CGPoint RSKRectCenterPoint(CGRect rect); | ||
|
||
// Returns the `rect` scaled around the `point` by `sx` and `sy`. | ||
CGRect RSKRectScaleAroundPoint(CGRect rect, CGPoint point, CGFloat sx, CGFloat sy); | ||
|
||
// Returns true if `point' is the null point, false otherwise. | ||
bool RSKPointIsNull(CGPoint point); | ||
|
||
// Returns the `point` rotated around the `pivot` by `angle`. | ||
CGPoint RSKPointRotateAroundPoint(CGPoint point, CGPoint pivot, CGFloat angle); | ||
|
||
// Returns the distance between two points. | ||
CGFloat RSKPointDistance(CGPoint p1, CGPoint p2); | ||
|
||
// Make a line segment from two points `start` and `end`. | ||
RSKLineSegment RSKLineSegmentMake(CGPoint start, CGPoint end); | ||
|
||
// Returns the line segment rotated around the `pivot` by `angle`. | ||
RSKLineSegment RSKLineSegmentRotateAroundPoint(RSKLineSegment lineSegment, CGPoint pivot, CGFloat angle); | ||
|
||
// Returns the intersection of `ls1' and `ls2'. This may return a null point. | ||
CGPoint RSKLineSegmentIntersection(RSKLineSegment ls1, RSKLineSegment ls2); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
// | ||
// CGGeometry+RSKImageCropper.m | ||
// | ||
// Copyright (c) 2015 Ruslan Skorb, http://ruslanskorb.com/ | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
// THE SOFTWARE. | ||
// | ||
|
||
#import "CGGeometry+RSKImageCropper.h" | ||
|
||
const CGPoint RSKPointNull = { INFINITY, INFINITY }; | ||
|
||
CGPoint RSKRectCenterPoint(CGRect rect) | ||
{ | ||
return CGPointMake(CGRectGetMinX(rect) + CGRectGetWidth(rect) / 2, | ||
CGRectGetMinY(rect) + CGRectGetHeight(rect) / 2); | ||
} | ||
|
||
CGRect RSKRectScaleAroundPoint(CGRect rect, CGPoint point, CGFloat sx, CGFloat sy) | ||
{ | ||
CGAffineTransform translationTransform, scaleTransform; | ||
translationTransform = CGAffineTransformMakeTranslation(-point.x, -point.y); | ||
rect = CGRectApplyAffineTransform(rect, translationTransform); | ||
scaleTransform = CGAffineTransformMakeScale(sx, sy); | ||
rect = CGRectApplyAffineTransform(rect, scaleTransform); | ||
translationTransform = CGAffineTransformMakeTranslation(point.x, point.y); | ||
rect = CGRectApplyAffineTransform(rect, translationTransform); | ||
return rect; | ||
} | ||
|
||
bool RSKPointIsNull(CGPoint point) | ||
{ | ||
return CGPointEqualToPoint(point, RSKPointNull); | ||
} | ||
|
||
CGPoint RSKPointRotateAroundPoint(CGPoint point, CGPoint pivot, CGFloat angle) | ||
{ | ||
CGAffineTransform translationTransform, rotationTransform; | ||
translationTransform = CGAffineTransformMakeTranslation(-pivot.x, -pivot.y); | ||
point = CGPointApplyAffineTransform(point, translationTransform); | ||
rotationTransform = CGAffineTransformMakeRotation(angle); | ||
point = CGPointApplyAffineTransform(point, rotationTransform); | ||
translationTransform = CGAffineTransformMakeTranslation(pivot.x, pivot.y); | ||
point = CGPointApplyAffineTransform(point, translationTransform); | ||
return point; | ||
} | ||
|
||
CGFloat RSKPointDistance(CGPoint p1, CGPoint p2) | ||
{ | ||
CGFloat dx = p1.x - p2.x; | ||
CGFloat dy = p1.y - p2.y; | ||
return sqrt(pow(dx, 2) + pow(dy, 2)); | ||
} | ||
|
||
RSKLineSegment RSKLineSegmentMake(CGPoint start, CGPoint end) | ||
{ | ||
return (RSKLineSegment){ start, end }; | ||
} | ||
|
||
RSKLineSegment RSKLineSegmentRotateAroundPoint(RSKLineSegment line, CGPoint pivot, CGFloat angle) | ||
{ | ||
return RSKLineSegmentMake(RSKPointRotateAroundPoint(line.start, pivot, angle), | ||
RSKPointRotateAroundPoint(line.end, pivot, angle)); | ||
} | ||
|
||
/* | ||
Equations of line segments: | ||
pA = ls1.start + uA * (ls1.end - ls1.start) | ||
pB = ls2.start + uB * (ls2.end - ls2.start) | ||
In the case when `pA` is equal `pB` we have: | ||
x1 + uA * (x2 - x1) = x3 + uB * (x4 - x3) | ||
y1 + uA * (y2 - y1) = y3 + uB * (y4 - y3) | ||
uA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3) / (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) | ||
uB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3) / (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) | ||
numeratorA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3) | ||
denominatorA = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) | ||
numeratorA = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3) | ||
denominatorB = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1) | ||
[1] Denominators are equal. | ||
[2] If numerators and denominator are zero, then the line segments are coincident. The point of intersection is the midpoint of the line segment. | ||
x = (x1 + x2) * 0.5 | ||
y = (y1 + y2) * 0.5 | ||
or | ||
x = (x3 + x4) * 0.5 | ||
y = (y3 + y4) * 0.5 | ||
[3] If denominator is zero, then the line segments are parallel. There is no point of intersection. | ||
[4] If `uA` and `uB` is included into the interval [0, 1], then the line segments intersects in the point (x, y). | ||
x = x1 + uA * (x2 - x1) | ||
y = y1 + uA * (y2 - y1) | ||
or | ||
x = x3 + uB * (x4 - x3) | ||
y = y3 + uB * (y4 - y3) | ||
*/ | ||
CGPoint RSKLineSegmentIntersection(RSKLineSegment ls1, RSKLineSegment ls2) | ||
{ | ||
CGFloat x1 = ls1.start.x; | ||
CGFloat y1 = ls1.start.y; | ||
CGFloat x2 = ls1.end.x; | ||
CGFloat y2 = ls1.end.y; | ||
CGFloat x3 = ls2.start.x; | ||
CGFloat y3 = ls2.start.y; | ||
CGFloat x4 = ls2.end.x; | ||
CGFloat y4 = ls2.end.y; | ||
|
||
CGFloat numeratorA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); | ||
CGFloat numeratorB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); | ||
CGFloat denominator = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); | ||
|
||
// Check the coincidence. | ||
if (fabs(numeratorA) < RSK_EPSILON && fabs(numeratorB) < RSK_EPSILON && fabs(denominator) < RSK_EPSILON) { | ||
return CGPointMake((x1 + x2) * 0.5, (y1 + y2) * 0.5); | ||
} | ||
|
||
// Check the parallelism. | ||
if (fabs(denominator) < RSK_EPSILON) { | ||
return RSKPointNull; | ||
} | ||
|
||
// Check the intersection. | ||
CGFloat uA = numeratorA / denominator; | ||
CGFloat uB = numeratorB / denominator; | ||
if (uA < 0 || uA > 1 || uB < 0 || uB > 1) { | ||
return RSKPointNull; | ||
} | ||
|
||
return CGPointMake(x1 + uA * (x2 - x1), y1 + uA * (y2 - y1)); | ||
} |
Oops, something went wrong.