2011-03-19 10:59:01 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2010-2011 cocos2d-x.org
|
|
|
|
Copyright (c) 2007 Scott Lembcke
|
|
|
|
Copyright (c) 2010 Lam Pham
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#ifndef __SUPPORT_CGPOINTEXTENSION_H__
|
|
|
|
#define __SUPPORT_CGPOINTEXTENSION_H__
|
|
|
|
|
2010-07-16 14:54:26 +08:00
|
|
|
/**
|
|
|
|
@file
|
2011-03-07 17:11:57 +08:00
|
|
|
CCPoint extensions based on Chipmunk's cpVect file.
|
|
|
|
These extensions work both with CCPoint and cpVect.
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
The "ccp" prefix means: "CoCos2d Point"
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
- ccpAdd( ccp(1,1), ccp(2,2) ); // preferred cocos2d way
|
2011-03-07 17:11:57 +08:00
|
|
|
- ccpAdd( CCPointMake(1,1), CCPointMake(2,2) ); // also ok but more verbose
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
- cpvadd( cpv(1,1), cpv(2,2) ); // way of the chipmunk
|
|
|
|
- ccpAdd( cpv(1,1), cpv(2,2) ); // mixing chipmunk and cocos2d (avoid)
|
2011-03-07 17:11:57 +08:00
|
|
|
- cpvadd( CCPointMake(1,1), CCPointMake(2,2) ); // mixing chipmunk and CG (avoid)
|
2011-03-19 10:59:01 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "CCGeometry.h"
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
namespace cocos2d {
|
|
|
|
|
2011-03-07 17:11:57 +08:00
|
|
|
/** Helper macro that creates a CCPoint
|
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-04-14 16:15:12 +08:00
|
|
|
#define ccp(__X__,__Y__) cocos2d::CCPointMake((float)__X__, (float)__Y__)
|
2011-03-19 10:59:01 +08:00
|
|
|
|
2010-07-16 14:54:26 +08:00
|
|
|
/** Returns opposite of point.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpNeg(const CCPoint& v)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(-v.x, -v.y);
|
2011-03-19 10:59:01 +08:00
|
|
|
}
|
|
|
|
|
2010-07-16 14:54:26 +08:00
|
|
|
/** Calculates sum of two points.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpAdd(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(v1.x + v2.x, v1.y + v2.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculates difference of two points.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpSub(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(v1.x - v2.x, v1.y - v2.y);
|
2011-03-19 10:59:01 +08:00
|
|
|
}
|
|
|
|
|
2010-07-16 14:54:26 +08:00
|
|
|
/** Returns point multiplied by given factor.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpMult(const CCPoint& v, const CGFloat s)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(v.x*s, v.y*s);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculates midpoint between two points.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpMidpoint(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccpMult(ccpAdd(v1, v2), 0.5f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculates dot product of two points.
|
|
|
|
@return CGFloat
|
|
|
|
@since v0.7.2
|
|
|
|
*/
|
|
|
|
static inline CGFloat
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpDot(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return v1.x*v2.x + v1.y*v2.y;
|
2011-03-19 10:59:01 +08:00
|
|
|
}
|
|
|
|
|
2010-07-16 14:54:26 +08:00
|
|
|
/** Calculates cross product of two points.
|
|
|
|
@return CGFloat
|
|
|
|
@since v0.7.2
|
|
|
|
*/
|
|
|
|
static inline CGFloat
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpCross(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return v1.x*v2.y - v1.y*v2.x;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculates perpendicular of v, rotated 90 degrees counter-clockwise -- cross(v, perp(v)) >= 0
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpPerp(const CCPoint& v)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(-v.y, v.x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculates perpendicular of v, rotated 90 degrees clockwise -- cross(v, rperp(v)) <= 0
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpRPerp(const CCPoint& v)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(v.y, -v.x);
|
2011-03-19 10:59:01 +08:00
|
|
|
}
|
|
|
|
|
2010-07-16 14:54:26 +08:00
|
|
|
/** Calculates the projection of v1 over v2.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpProject(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccpMult(v2, ccpDot(v1, v2)/ccpDot(v2, v2));
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Rotates two points.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpRotate(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(v1.x*v2.x - v1.y*v2.y, v1.x*v2.y + v1.y*v2.x);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Unrotates two points.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
static inline CCPoint
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpUnrotate(const CCPoint& v1, const CCPoint& v2)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccp(v1.x*v2.x + v1.y*v2.y, v1.y*v2.x - v1.x*v2.y);
|
2011-03-19 10:59:01 +08:00
|
|
|
}
|
|
|
|
|
2011-03-07 17:11:57 +08:00
|
|
|
/** Calculates the square length of a CCPoint (not calling sqrt() )
|
2010-07-16 14:54:26 +08:00
|
|
|
@return CGFloat
|
|
|
|
@since v0.7.2
|
|
|
|
*/
|
|
|
|
static inline CGFloat
|
2011-04-16 14:55:02 +08:00
|
|
|
ccpLengthSQ(const CCPoint& v)
|
2010-07-16 14:54:26 +08:00
|
|
|
{
|
|
|
|
return ccpDot(v, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Calculates distance between point an origin
|
|
|
|
@return CGFloat
|
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CGFloat CC_DLL ccpLength(const CCPoint& v);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Calculates the distance between two points
|
|
|
|
@return CGFloat
|
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CGFloat CC_DLL ccpDistance(const CCPoint& v1, const CCPoint& v2);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Returns point multiplied to a length of 1.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CCPoint CC_DLL ccpNormalize(const CCPoint& v);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Converts radians to a normalized vector.
|
2011-03-07 17:11:57 +08:00
|
|
|
@return CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
CCPoint CC_DLL ccpForAngle(const CGFloat a);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Converts a vector to radians.
|
|
|
|
@return CGFloat
|
|
|
|
@since v0.7.2
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CGFloat CC_DLL ccpToAngle(const CCPoint& v);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
/** Clamp a value between from and to.
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-03-07 17:11:57 +08:00
|
|
|
float CC_DLL clampf(float value, float min_inclusive, float max_inclusive);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Clamp a point between from and to.
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CCPoint CC_DLL ccpClamp(const CCPoint& p, const CCPoint& from, const CCPoint& to);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
2011-03-07 17:11:57 +08:00
|
|
|
/** Quickly convert CCSize to a CCPoint
|
2010-07-16 14:54:26 +08:00
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CCPoint CC_DLL ccpFromSize(const CCSize& s);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Run a math operation function on each point component
|
|
|
|
* absf, fllorf, ceilf, roundf
|
|
|
|
* any function that has the signature: float func(float);
|
|
|
|
* For example: let's try to take the floor of x,y
|
|
|
|
* ccpCompOp(p,floorf);
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CCPoint CC_DLL ccpCompOp(const CCPoint& p, float (*opFunc)(float));
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Linear Interpolation between two points a and b
|
|
|
|
@returns
|
|
|
|
alpha == 0 ? a
|
|
|
|
alpha == 1 ? b
|
|
|
|
otherwise a value between a..b
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CCPoint CC_DLL ccpLerp(const CCPoint& a, const CCPoint& b, float alpha);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
/** @returns if points have fuzzy equality which means equal with some degree of variance.
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
bool CC_DLL ccpFuzzyEqual(const CCPoint& a, const CCPoint& b, float variance);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
/** Multiplies a nd b components, a.x*b.x, a.y*b.y
|
|
|
|
@returns a component-wise multiplication
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CCPoint CC_DLL ccpCompMult(const CCPoint& a, const CCPoint& b);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** @returns the signed angle in radians between two vector directions
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
float CC_DLL ccpAngleSigned(const CCPoint& a, const CCPoint& b);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** @returns the angle in radians between two vector directions
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
float CC_DLL ccpAngle(const CCPoint& a, const CCPoint& b);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** Rotates a point counter clockwise by the angle around a pivot
|
|
|
|
@param v is the point to rotate
|
|
|
|
@param pivot is the pivot, naturally
|
|
|
|
@param angle is the angle of rotation cw in radians
|
|
|
|
@returns the rotated point
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-04-16 14:55:02 +08:00
|
|
|
CCPoint CC_DLL ccpRotateByAngle(const CCPoint& v, const CCPoint& pivot, float angle);
|
2010-07-16 14:54:26 +08:00
|
|
|
|
|
|
|
/** A general line-line intersection test
|
|
|
|
@param p1
|
|
|
|
is the startpoint for the first line P1 = (p1 - p2)
|
|
|
|
@param p2
|
|
|
|
is the endpoint for the first line P1 = (p1 - p2)
|
|
|
|
@param p3
|
|
|
|
is the startpoint for the second line P2 = (p3 - p4)
|
|
|
|
@param p4
|
|
|
|
is the endpoint for the second line P2 = (p3 - p4)
|
|
|
|
@param s
|
|
|
|
is the range for a hitpoint in P1 (pa = p1 + s*(p2 - p1))
|
|
|
|
@param t
|
|
|
|
is the range for a hitpoint in P3 (pa = p2 + t*(p4 - p3))
|
|
|
|
@return bool
|
|
|
|
indicating successful intersection of a line
|
|
|
|
note that to truly test intersection for segments we have to make
|
|
|
|
sure that s & t lie within [0..1] and for rays, make sure s & t > 0
|
|
|
|
the hit point is p3 + t * (p4 - p3);
|
|
|
|
the hit point also is p1 + s * (p2 - p1);
|
|
|
|
@since v0.99.1
|
|
|
|
*/
|
2011-07-08 14:16:10 +08:00
|
|
|
bool CC_DLL ccpLineIntersect(const CCPoint& p1, const CCPoint& p2,
|
|
|
|
const CCPoint& p3, const CCPoint& p4,
|
2011-03-19 10:59:01 +08:00
|
|
|
float *s, float *t);
|
|
|
|
|
2011-07-08 14:16:10 +08:00
|
|
|
/*
|
|
|
|
ccpSegmentIntersect returns YES if Segment A-B intersects with segment C-D
|
|
|
|
@since v1.0.0
|
|
|
|
*/
|
2011-07-11 15:33:27 +08:00
|
|
|
bool CC_DLL ccpSegmentIntersect(const CCPoint& A, const CCPoint& B, const CCPoint& C, const CCPoint& D);
|
2011-07-08 14:16:10 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
ccpIntersectPoint returns the intersection point of line A-B, C-D
|
|
|
|
@since v1.0.0
|
|
|
|
*/
|
2011-07-11 15:33:27 +08:00
|
|
|
CCPoint CC_DLL ccpIntersectPoint(const CCPoint& A, const CCPoint& B, const CCPoint& C, const CCPoint& D);
|
2011-07-08 14:16:10 +08:00
|
|
|
|
2011-03-19 10:59:01 +08:00
|
|
|
}//namespace cocos2d
|
|
|
|
|
|
|
|
#endif // __SUPPORT_CGPOINTEXTENSION_H__
|
|
|
|
|