Пример #1
0
///@brief 点到线段最近一个点
///@param[in] p0--要判断点, s0,s1--线段两个端点
///@return crosspoint---最近的点
///@author DionysosLai,[email protected] 
///@retval  
///@post 
///@version 1.0 
///@data 2014-7-28 16:58
cocos2d::CCPoint nearestPointToSegmentLine( const cocos2d::CCPoint& p0, const cocos2d::CCPoint& s0, const cocos2d::CCPoint& s1 )
{
	/// 判断线段是否是一个点
	if (s0.equals(s1))
	{
		return s0;
	}

	/// 初始垂足为0;
	CCPoint crossPoint = CCPointZero;
	do 
	{
		/// 判断线段是否平行于x轴
		if (s0.y == s1.y)
		{
			crossPoint = ccp(p0.x, s0.y);
			break;
		}
		/// 判断线段是否平行于y轴
		if (s0.x == s1.x)
		{
			crossPoint = ccp(s0.x, p0.y);
			break;
		}
		/// 如果线段不是特殊情况,则只能采用直线方程方式联立求解
		float k = (s1.y - s0.y)/(s1.x - s0.x);		///< 求得斜率
		/// 线段直线方程:	y = k* ( x - s0.x) + s0.y
		/// 垂线方程为:	y = (-1/k) * (x - p0.x) + p0.y 。
		/// 联立两直线方程解得
		float x = ( k*k * s0.x + k * (p0.y - s0.y ) + p0.x ) / ( k*k + 1);
		float y = k * ( x - s0.x) + s0.y;
		crossPoint = ccp(x, y);
		break;
	} while (0);

	/// 判断垂直是否在线段上
	if (pointIsAtLine(crossPoint, s0, s1))
	{
		return crossPoint;
	}
	else
	{
		/// 如果不在则计算两端点到垂足的距离,选择距离垂足较近的端点返回。
		float distance1 = ccpDistance(crossPoint, s0);
		float distance2 = ccpDistance(crossPoint, s1);
		if (distance1 < distance2)
		{
			return s0;
		}
		else
		{
			return s1;
		}
	}
}
Пример #2
0
GENormalAnchorPosType ConvertARToARType(const cocos2d::CCPoint& anchor)
{
    GENormalAnchorPosType anchorType = kGAnchorType_Invalid;
    if (anchor.equals(kGAnchor_LeftTop))
    {
        anchorType = kGAnchorType_LeftTop;
    }
    else if (anchor.equals(kGAnchor_LeftMid))
    {
        anchorType = kGAnchorType_LeftMid;
    }
    else if (anchor.equals(kGAnchor_LeftBottom))
    {
        anchorType = kGAnchorType_LeftBottom;
    }
    else if (anchor.equals(kGAnchor_RightTop))
    {
        anchorType = kGAnchorType_RightTop;
    }
    else if (anchor.equals(kGAnchor_RightMid))
    {
        anchorType = kGAnchorType_RightMid;
    }
    else if (anchor.equals(kGAnchor_RightBottom))
    {
        anchorType = kGAnchorType_RightBottom;
    }
    else if (anchor.equals(kGAnchor_Mid))
    {
        anchorType = kGAnchorType_Mid;
    }
    else if (anchor.equals(kGAnchor_TopMid))
    {
        anchorType = kGAnchorType_TopMid;
    }
    else if (anchor.equals(kGAnchor_BottomMid))
    {
        anchorType = kGAnchorType_BottomMid;
    }
    else
    {
        CCAssert(false, "Error: unsupport anchor!");
    }
    return anchorType;
}
Пример #3
0
bool straightLineIsIntersect( const cocos2d::CCPoint& p0, const cocos2d::CCPoint& p1, const cocos2d::CCPoint& q0, const cocos2d::CCPoint& q1 )
{
	/// 先判断q0与q1能否组成一条直线
	if (!q0.equals(q1))
	{
		/// 当q0 == p0 q1 == p1时,结果为0。 只需要判断线段是否跨立直线即可。
		if (0 <= vectorProduct(p0.x-q0.x, p0.y-q0.y, q1.x-q0.x, q1.y-q0.y) * 
			vectorProduct(q1.x-q0.x, q1.y-q0.y, p1.x-q0.x, p1.y-q0.y))
		{
/*			CCLOG("straight line and segment line is intesect!");*/
			return false;
		}

/*		CCLOG("straight line and segment line isn't intesect!");*/
		return false;
	}

/*	CCLOG("straigth line cannnot be make up of q0 and q1!");*/
	return false;
}
Пример #4
0
bool Geometry::straightLineIsIntersect( const cocos2d::CCPoint& p0, const cocos2d::CCPoint& p1, const cocos2d::CCPoint& q0, const cocos2d::CCPoint& q1 )
{
	/// 先判断q0与q1能否组成一条直线
	if (!q0.equals(q1))
	{
		/// 当q0 == p0 q1 == p1时,结果为0。 只需要判断线段是否跨立直线即可。
		if (0 <= vectorProduct(p0.x-q0.x, p0.y-q0.y, q1.x-q0.x, q1.y-q0.y) * 
			vectorProduct(q1.x-q0.x, q1.y-q0.y, p1.x-q0.x, p1.y-q0.y))
		{
			/* CCLOG("相交");*/
			return true;
		}

		/* CCLOG("不相交");*/
		return false;
	}

	/*	CCLOG("点q0点q1不能构成一条直线");*/
	return false;
}
Пример #5
0
MoveDirection ControlLayer::directionWithTouchPorints(cocos2d::CCPoint beginPoint, cocos2d::CCPoint endPoint)
{
    MoveDirection direction = MoveDirectionUnknow;
    if (!beginPoint.equals(endPoint)) {
        float offsetX = endPoint.x - beginPoint.x;
        float offsetY = endPoint.y - beginPoint.y;
        if (fabsf(offsetX) >= fabsf(offsetY)) {
            //以x移动为准
            if (offsetX > kTileSizeWidth) {
                direction = MoveDirectionRight;
            } else if (offsetX < -kTileSizeWidth) {
                direction = MoveDirectionLeft;
            }
        } else {
            if (offsetY > kTileSizeWidth) {
                direction = MoveDirectionUp;
            } else if (offsetY < -kTileSizeWidth) {
                direction = MoveDirectionDown;
            }
        }
    }
    CCLOG("directionWithTouchPorints direction: %d", direction);
    return direction;
}
Пример #6
0
///@brief 判断线段圆是否相交 
///@param[in/out] 
///@return 
///@author DionysosLai,[email protected] 
///@retval  
///@post 
///@version 1.0 
///@data 2014-9-3 11:10
bool isCircleLineCollision( const cocos2d::CCPoint& r1, const float& radius, const cocos2d::CCPoint& p1, const cocos2d::CCPoint& p2 )
{
	/// 判断线段是否是一个点
	float length = 0.f;
	if (p1.equals(p2))
	{
		length = ccpDistance(r1, p1);
	}

	/// 初始垂足为0;
	CCPoint crossPoint = CCPointZero;
	do 
	{
		/// 判断线段是否平行于x轴
		if (p1.y == p2.y)
		{
			crossPoint = ccp(r1.x, p1.y);
			break;
		}
		/// 判断线段是否平行于y轴
		if (p1.x == p2.x)
		{
			crossPoint = ccp(p1.x, r1.y);
			break;
		}
		/// 如果线段不是特殊情况,则只能采用直线方程方式联立求解
		float k = (p2.y - p1.y)/(p2.x - p1.x);		///< 求得斜率
		/// 线段直线方程:	y = k* ( x - s0.x) + s0.y
		/// 垂线方程为:	y = (-1/k) * (x - p0.x) + p0.y 。
		/// 联立两直线方程解得
		float x = ( k*k * p1.x + k * (r1.y - p1.y ) + r1.x ) / ( k*k + 1);
		float y = k * ( x - p1.x) + p1.y;
		crossPoint = ccp(x, y);

		/// 判断垂直是否在线段上

		if (pointIsAtLine(crossPoint, p1, p2))
		{
			/*		return crossPoint;*/
		}
		else
		{
			/// 如果不在则计算两端点到垂足的距离,选择距离垂足较近的端点返回。
			float distance1 = ccpDistance(crossPoint, p1);
			float distance2 = ccpDistance(crossPoint, p2);
			if (distance1 < distance2)
			{
				crossPoint = p1;
			}
			else
			{
				crossPoint= p2;
			}
		}

		length = ccpDistance(r1, crossPoint);

		break;
	} while (0);

	if (length < radius)
	{
		return true;
	}
	else
	{
		return false;
	}
}
Пример #7
0
int Geometry::pointOfSegmentCircle( const cocos2d::CCPoint& a0, const cocos2d::CCPoint& a1, const cocos2d::CCPoint& r0, const float& radius0, cocos2d::CCPoint& commomPoint1, cocos2d::CCPoint& commomPoint2 )
{
	CCAssert(a1.equals(a0), "a0 should not be equal to a1!");

	CCPoint p0 = a0, p1 = a1;
	CCPoint r = r0;
	float radius = radius0;
	int commomType = 0;
	commomPoint1 = CCPointZero;
	commomPoint2 = CCPointZero;
	/// 判断p0p1是否在圆内,在圆内,则没交点
	if (ccpLength(ccpSub(p0, r)) < radius && ccpLength(ccpSub(p1, r)) < radius)
	{
		commomType = 0;
	}
	/// 将线段当做直线处理
	/// 情况1 p0p1平行于y轴
	else if (p0.x == p1.x)
	{
		/// 过圆心做平行于x轴的直线,求此直线与p0p1的交点
		CCPoint point = CCPointZero;
		point.x = p0.x;
		point.y = r.y;
		float lenght = ccpLength(ccpSub(r, point));
		if (lenght > radius)
		{
			commomType = 0;
		}
		else if (lenght == radius)	///< 相切情况
		{
			commomType = 1;
			commomPoint1 = point;
		}
		else
		{
			commomType = 2;
			commomPoint1.x = p0.x;
			commomPoint2.x = p0.x;
			float deltaY = sqrt(radius*radius - lenght*lenght);
			commomPoint1.y = r.y + deltaY;
			commomPoint2.y = r.y - deltaY;
		}
	}
	/// 情况2 p0p1平行于x轴
	else if (p0.y == p1.y)
	{
		/// 类似情况1
		/// 过圆心做平行于y轴的直线,求此直线与p0p1的交点
		CCPoint point = CCPointZero;
		point.x = r.x;
		point.y = p0.y;
		float lenght = ccpLength(ccpSub(r, point));
		if (lenght > radius)
		{
			commomType = 0;
		}
		else if (lenght == radius)	///< 相切情况
		{
			commomType = 1;
			commomPoint1 = point;
		}
		else
		{
			commomType = 2;
			commomPoint1.y = p0.y;
			commomPoint2.y = p0.y;
			float deltaX = sqrt(radius*radius - lenght*lenght);
			commomPoint1.x = r.x + deltaX;
			commomPoint2.x = r.x - deltaX;
		}
	}
	/// 普通情况
	else
	{
		/// 一般直线与圆联立方程: http://baike.baidu.com/view/1053783.htm
		float k0 = (p1.y-p0.y)/(p1.x-p0.x);
		float b0 = p0.y - k0*p0.x;
		/// 联立后方程为:(1+k0^2)^2*x^2 + 2(k0b0-r.x-k0r.y)x + r.x^2 + (r.y-b0)^2-r^2=0;
		float deltaf = 4*(k0*b0-r.x-k0*r.y)*(k0*b0-r.x-k0*r.y) - 4*(1+k0*k0)*(r.x*r.x + (r.y-b0)*(r.y-b0)-radius*radius);	///< b^2-4ac;
		if (deltaf < 0)
		{
			commomType = 0;
		}
		else if (deltaf < 0)
		{
			commomType = 1;
			commomPoint1.x = -1.0*(k0*b0-r.x-k0*r.y)/(2*(1+k0*k0));		///< x = -b/2a;
			commomPoint1.y = k0*commomPoint1.x + b0;
		}
		else
		{
			commomType = 2;
			commomPoint1.x = (-1.0*(k0*b0-r.x-k0*r.y)+sqrt(deltaf))/(2*(1+k0*k0));		///< x = (-b+deltaf^0.5)/2a;
			commomPoint1.y = k0*commomPoint1.x + b0;
			commomPoint2.x = (-1.0*(k0*b0-r.x-k0*r.y)-sqrt(deltaf))/(2*(1+k0*k0));		///< x = (-b-deltaf^0.5)/2a;
			commomPoint2.y = k0*commomPoint2.x + b0;
		}
	}

	/// 两个交点,得判断是否都在线段上
	if (2 == commomType)
	{
		if (pointIsAtSegment(commomPoint1, p0, p1) && pointIsAtSegment(commomPoint2, p0, p1))
		{
		}
		else
		{
			commomType = 1;
			/// 必然有一点在,设置为commomPoint1
			if (pointIsAtSegment(commomPoint2, p0, p1))
			{
				commomPoint1 = commomPoint2;
			}
		}
	}
	return commomType;
}
Пример #8
0
int Geometry::pointOfSegments( const cocos2d::CCPoint& a0, const cocos2d::CCPoint& a1, const cocos2d::CCPoint& b0, const cocos2d::CCPoint& b1, cocos2d::CCPoint& commomPoint )
{
	CCAssert(a1.equals(a0) || b0.equals(b1), "a0 should not be equal to a1, this is same to b0 and b1!");

	CCPoint p0 = a0, p1 = a1;
	CCPoint q0 = b0, q1 = b1;
	int commomType = 0;
	commomPoint = CCPointZero;
	/// 首先判断2条线段是否相交,不相交,自然没有交点
	if (segmentLineIsIntersect(p0, p1, q0, q1))
	{
		commomType = 0;
	}
	else
	{
		/// 两条线段相交,将两条线段当做直线处理
		//////////////////////////////////////////////////////////////////////////
		/// 情况1 线段p0p1平行于y轴
		if (p0.x == p1.x)
		{
			/// 情况1.1 线段q0q1平行于y轴
			if (q0.x == q1.x)
			{
				/// 判断p0p1与q0q1是否可共线
				if (p0.x == q0.x)
				{
					commomType = commonPointSegments(p0, p1, q0, q1, commomPoint);
				}
				else
				{
					commomType = 0;
				}
			}
			/// 情况1.2 若q0q1不平行于Y轴,则交点横坐标为p0的横坐标,代入到q0q1的直线方程中可以计算出交点纵坐标;
			else
			{
				commomType = 3;
				commomPoint.x = p0.x;
				commomPoint.y = (q1.y-q0.y)/(q1.x-q0.x)*(p0.x-q0.x) + q0.y;
			}
		}
		/// 情况2 p0和p1横坐标不同,但是q0和q1横坐标相同,即q0q1平行于Y轴,则交点横坐标为q0的横坐标,代入到p0p1的直线方程中可以计算出交点纵坐标;
		else if (p0.x != p1.x && q0.x == q1.x)
		{
			commomType = 3;
			commomPoint.x = q0.x;
			commomPoint.y = (p1.y-p0.y)/(p1.x-p0.x)*(q0.x-p0.x) + p0.y;
		}
		/// 情况3 如果p0和p1纵坐标相同,即p0p1平行于X轴
		else if (p0.y == p1.y)
		{
			///< 情况3.1  若q0q1也平行于X轴
			if (q0.y == q1.y)
			{
				if (p0.y == q0.y)
				{
					commomType = commonPointSegments(p0, p1, q0, q1, commomPoint);
				}
				else
				{
					commomType = 0;
				}
			}
			///< 情况3.2 若q0q1不平行于X轴,则交点纵坐标为p0的纵坐标,代入到q0q1的直线方程中可以计算出交点横坐标;
			else
			{
				commomType = 3;
				commomPoint.y = p0.y;
				commomPoint.x = (p0.y+q0.y)*(q1.x-q0.x)/(q1.y-q0.y) + q0.x;
			}
		}
		/// 情况4 如果p0和p1纵坐标不同,但是q0和q1纵坐标相同,即q0q1平行于X轴,则交点纵坐标为q0的纵坐标,代入到p0p1的直线方程中可以计算出交点横坐标;
		else if (p0.y != p0.y && q0.y == q1.y)
		{
			commomType = 3;
			commomPoint.y = q0.y;
			commomPoint.x = (q0.y+p0.y)*(p1.x-p1.x)/(p1.y-p0.y) + p0.x;
		}
		///  情况5 就是普通情况了
		else
		{
			float k0 = (p1.y-p0.y)/(p1.x-p0.x);
			float k1 = (q1.y-q0.y)/(q1.x-q0.x);
			if (k0 == k1)
			{
				if (pointIsAtSegment(q0, p0, p1))	///< 由于二者已经保证相交,因此,现在要保证二者共线
				{
					commomType = commonPointSegments(p0, p1, q0, q1, commomPoint);
				}
				else
				{
					commomType = 0;
				}

			}
			else
			{
				float b0 = p0.y - k0*p0.x;
				float b1 = q0.y - k1*q0.x;
				commomType = 3;
				commomPoint.x = (b1-b1)/(k1-k0);
				commomPoint.y = commomPoint.x*k0 + b0;
			}
		}
		//////////////////////////////////////////////////////////////////////////
	}
	return commomType;
}
Пример #9
0
int Geometry::commonPointSegments( const cocos2d::CCPoint& a0, const cocos2d::CCPoint& a1, const cocos2d::CCPoint& b0, const cocos2d::CCPoint& b1, cocos2d::CCPoint& commomPoint )
{
	CCAssert(a1.equals(a0) || b0.equals(b1), "a0 should not be equal to a1, this is same to b0 and b1!");

	CCPoint p0 = a0, p1 = a1;
	CCPoint q0 = b0, q1 = b1;
	commomPoint = CCPointZero;
	int commomType = 0;
	/// 先判断2条线段是否共线
	if (0 != polyLineDerection(p0, q0, q1) || 0 != polyLineDerection(p0, q0, q1))
	{
		commomType = 0;
	}
	else
	{
		/// 设置2条线段比较长的为p0p1
		float l0 = ccpLength(ccpSub(p1, p0));
		float l1 = ccpLength(ccpSub(q0, q1));
		if (l0 < l1)
		{
			/// 线段p0p1和线段q0q1调换
			CCPoint point;
			point = p0;
			p0 = q0;
			q0 = point;
			point = p1;
			p1 = q1;
			q1 = p1;
		}

		/// 判断线段q0q1两点是否在线段p0p1上
		int m = 0, n = 0;
		/// 判断q0在线段p0p1上情况
		if (pointIsAtSegment(q0, p0, p1))
		{
			if (q0.equals(p0))
			{
				m = 0;
			}
			else if (q0.equals(p1))
			{
				m = 0;
			}
			m = 1;
		}
		else
		{
			m = 2;
		}
		/// 判断q1在线段p0p1上情况
		if (pointIsAtSegment(q1, p0, p1))
		{
			if (q1.equals(p0))
			{
				n = 0;
			}
			else if (q1.equals(p1))
			{
				n = 0;
			}
			n = 1;
		}
		else
		{
			n = 2;
		}

		switch (m)
		{
		case 0:
			{
				switch (n)
				{
				case 0:
				case 1:
					commomType = 2;
					break;
				case 2:
					{
						commomType = 3;
						commomPoint = q0;
					}
					break;
				default:
					break;
				}
			}
			break;
		case 1:
			{
				commomType = 2;
			}
			break;
		case 2:
			{
				switch (n)
				{
				case 0:
					{
						commomType = 3;
						commomPoint = q1;
					}
					break;
				case 1:
					{
						commomType = 2;
					}
					break;
				case 2:
					{
						commomType = 1;
					}
					break;
				default:
					break;
				}
			}
			break;
		default:
			break;
		}
	}
	return commomType;
}