//点和圆碰撞 public static bool CollidePointAndCircle(GameVector2 _p, GameVector2 _c, int _radius) { long sprRadius = _radius * _radius; long sqrDistance = _c.sqrMagnitude(_p); return(sqrDistance < sprRadius); }
//圆和圆碰撞 public static bool CollideCircleAndCircle(GameVector2 _c1, GameVector2 _c2, int _radius1, int _radius2) { int sumRadius = _radius1 + _radius2; long sprRadius = sumRadius * sumRadius; long sqrDistance = _c1.sqrMagnitude(_c2); return(sqrDistance < sprRadius); }
// 圆和正圆扇面的碰撞,不带位置修正 public static bool CollideCircleAndArcArea(GameVector2 _c1, int _radius1, GameVector2 _arcCen, int _arcRadius, int _arcAngle, int _arcAngleSize) { int radiusSum = _radius1 + _arcRadius; long sqrRadiusSum = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_arcCen); if (sqrDistance >= sqrRadiusSum) { return(false); } int _angle = (_c1 - _arcCen).Angle(); int _point1Angle = _arcAngle + _arcAngleSize; int _point2Angle = _arcAngle - _arcAngleSize; bool inArc; if (_point2Angle < 0) { int _angle1 = (int)Mathf.Repeat(_angle - _point2Angle, 360f); if (_angle1 >= 0 && _angle1 <= (_point1Angle - _point2Angle)) { inArc = true; } else { inArc = false; } } else if (_point1Angle > 360) { int _delA = _point1Angle - 360; int _angle1 = (int)Mathf.Repeat(_angle - _delA, 360f); if (_angle1 >= (_point2Angle - _delA) && _angle1 <= 360) { inArc = true; } else { inArc = false; } } else { if (_angle >= _point2Angle && _angle <= _point1Angle) { inArc = true; } else { inArc = false; } } if (inArc) { return(true); } return(false); }
/// <summary> /// 点和圆的碰撞,圆不动修正点的位置 /// </summary> /// <returns><c>true</c>, if point and circle was collided, <c>false</c> otherwise.</returns> /// <param name="_p">碰撞点.</param> /// <param name="_c">碰撞圆心.</param> /// <param name="_radius">圆半径.</param> /// <param name="_amend">修正值.</param> public static bool CollidePointAndCircle(GameVector2 _p, GameVector2 _c, int _radius, out GameVector2 _amend) { _amend = GameVector2.zero; long sprRadius = _radius * _radius; long sqrDistance = _c.sqrMagnitude(_p); if (sqrDistance >= sprRadius) { return(false); } int distance = (int)Mathf.Sqrt(sqrDistance); int _angle = (_p - _c).Angle(); int amendDis = 1 + (_radius - distance) / 100; _amend = amendDis * BattleData.Instance.GetSpeed(_angle); return(true); }
// 圆和正圆弧的碰撞,不带位置修正 public static bool CollideCircleAndArc(GameVector2 _c1, int _radius1, GameVector2 _arcCen, int _arcRadius, int _arcAngle, int _arcAngleSize) { int radiusSum = _radius1 + _arcRadius; long sqrRadiusSum = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_arcCen); if (sqrDistance >= sqrRadiusSum) { return(false); } int radiusDel = _radius1 - _arcRadius; long sqrRadiusDel = radiusDel * radiusDel; if (sqrDistance <= sqrRadiusDel) { return(false); } int _angle = (_c1 - _arcCen).Angle(); if (Mathf.Abs(_angle - _arcAngle) <= _arcAngleSize) { return(true); } int _point1Angle = (int)Mathf.Repeat(_arcAngle + _arcAngleSize, 360); GameVector2 _point1 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point1Angle); bool _result1 = ToolGameVector.CollidePointAndCircle(_c1, _point1, _radius1); if (_result1) { return(_result1); } int _point2Angle = (int)Mathf.Repeat(_arcAngle - _arcAngleSize, 360); GameVector2 _point2 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point2Angle); bool _result2 = ToolGameVector.CollidePointAndCircle(_c1, _point2, _radius1); if (_result2) { return(_result2); } return(false); }
/// <summary> /// 圆和圆的碰撞,2个圆的位置都修正 /// </summary> /// <returns><c>true</c>, if circle and circle was collided, <c>false</c> otherwise.</returns> /// <param name="_c1">圆1的圆心.</param> /// <param name="_c2">圆2的圆心.</param> /// <param name="_radius1">圆1的半径.</param> /// <param name="_radius2">圆2的半径.</param> /// <param name="_amend1">圆1的修正值.</param> /// <param name="_amend2">圆2的修正值.</param> public static bool CollideCircleAndCircle(GameVector2 _c1, GameVector2 _c2, int _radius1, int _radius2, out GameVector2 _amend1, out GameVector2 _amend2) { _amend1 = GameVector2.zero; _amend2 = GameVector2.zero; int radiusSum = _radius1 + _radius2; long sprRadius = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_c2); if (sqrDistance >= sprRadius) { return(false); } int distance = (int)Mathf.Sqrt(sqrDistance); int _angle = (_c1 - _c2).Angle(); int amendDis = 1 + (int)((radiusSum - distance) * 0.5) / 100; _amend1 = amendDis * BattleData.Instance.GetSpeed(_angle); _amend2 = -1 * _amend1; return(true); }
public static bool IsInDistance(GameVector2 _pos1, GameVector2 _pos2, long _distance, out long _realdis) { _realdis = _pos1.sqrMagnitude(_pos2); return(_realdis <= _distance * _distance); }
/// <summary> /// 圆和正圆扇面的碰撞,带位置修正 /// </summary> /// <returns><c>true</c>, if circle and arc was collided, <c>false</c> otherwise.</returns> /// <param name="_c1">圆心.</param> /// <param name="_radius1">圆半径.</param> /// <param name="_arcCen">扇面圆心.</param> /// <param name="_arcRadius">扇面所在圆半径.</param> /// <param name="_arcAngle">角度.</param> /// <param name="_arcAngleSize">角度范围.</param> /// <param name="_amend">修正值.</param> public static bool CollideCircleAndArcArea(GameVector2 _c1, int _radius1, GameVector2 _arcCen, int _arcRadius, int _arcAngle, int _arcAngleSize, out GameVector2 _amend) { _amend = GameVector2.zero; int radiusSum = _radius1 + _arcRadius; long sqrRadiusSum = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_arcCen); if (sqrDistance >= sqrRadiusSum) { return(false); } int _angle = (_c1 - _arcCen).Angle(); int _point1Angle = _arcAngle + _arcAngleSize; int _point2Angle = _arcAngle - _arcAngleSize; bool inArc; if (_point2Angle < 0) { int _angle1 = (int)Mathf.Repeat(_angle - _point2Angle, 360f); if (_angle1 >= 0 && _angle1 <= (_point1Angle - _point2Angle)) { inArc = true; } else { inArc = false; } } else if (_point1Angle > 360) { int _delA = _point1Angle - 360; int _angle1 = (int)Mathf.Repeat(_angle - _delA, 360f); if (_angle1 >= (_point2Angle - _delA) && _angle1 <= 360) { inArc = true; } else { inArc = false; } } else { if (_angle >= _point2Angle && _angle <= _point1Angle) { inArc = true; } else { inArc = false; } } if (inArc) { //在圆弧内,需要修正 int distance = (int)Mathf.Sqrt(sqrDistance); int amendDis = 1 + (int)(radiusSum - distance) / 100; _amend = amendDis * BattleData.Instance.GetSpeed(_angle); return(true); } //线段修正 Vector3 _circleCenter = ToolGameVector.ChangeGameVectorToVector3(_c1); Vector3 _arcAreaCenter = ToolGameVector.ChangeGameVectorToVector3(_arcCen); _point1Angle = (int)Mathf.Repeat(_point1Angle, 360); GameVector2 _point1 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point1Angle); _point2Angle = (int)Mathf.Repeat(_point2Angle, 360); GameVector2 _point2 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point2Angle); Vector3 _line1Point = ToolGameVector.ChangeGameVectorToVector3(_point1); Vector3 _line2Point = ToolGameVector.ChangeGameVectorToVector3(_point2); //线段1修正 bool amendline1 = false; GameVector2 amendLine1P = GameVector2.zero; Vector3 _circleVec = _circleCenter - _arcAreaCenter; Vector3 _line = _line1Point - _arcAreaCenter; Vector3 _cross = Vector3.Cross(_circleVec, _line); if (_cross.z <= 0) { //在线段的左侧,即多边形的外侧 Vector3 vecProj = Vector3.Project(_circleVec, _line); //投影点 float disLine = _line.magnitude; float proj_begin = vecProj.magnitude; float proj_end = (vecProj - _line).magnitude; float projlengh = proj_begin + proj_end; if ((disLine + 1) >= projlengh) { //投影在线段上 int dis = (int)Mathf.Sqrt(_circleVec.sqrMagnitude - vecProj.sqrMagnitude); int disRadius = _radius1 / 100; if (dis < disRadius) { //需要修正 amendline1 = true; int amendDis = 1 + (int)(_radius1 / 100 - dis); Vector3 angelVec = _circleVec - vecProj; float angle1 = Mathf.Atan2(angelVec.y, angelVec.x) * Mathf.Rad2Deg; int amendAngle = (int)Mathf.Repeat(angle1, 360f); amendLine1P = amendDis * BattleData.Instance.GetSpeed(amendAngle); } } else { //投影不在当前线段上 } } //线段2修正 bool amendline2 = false; GameVector2 amendLine2P = GameVector2.zero; Vector3 _circleVec2 = _circleCenter - _line2Point; Vector3 _line2 = _arcAreaCenter - _line2Point; Vector3 _cross2 = Vector3.Cross(_circleVec2, _line2); if (_cross2.z <= 0) { //在线段的左侧,即多边形的外侧 Vector3 vecProj = Vector3.Project(_circleVec2, _line2); //投影点 float disLine = _line2.magnitude; float proj_begin = vecProj.magnitude; float proj_end = (vecProj - _line2).magnitude; float projlengh = proj_begin + proj_end; if ((disLine + 1) >= projlengh) { //投影在线段上 int dis = (int)Mathf.Sqrt(_circleVec2.sqrMagnitude - vecProj.sqrMagnitude); int disRadius = _radius1 / 100; if (dis < disRadius) { //需要修正 amendline2 = true; int amendDis = 1 + (int)(_radius1 / 100 - dis); Vector3 angelVec = _circleVec2 - vecProj; float angle1 = Mathf.Atan2(angelVec.y, angelVec.x) * Mathf.Rad2Deg; int amendAngle = (int)Mathf.Repeat(angle1, 360f); amendLine2P = amendDis * BattleData.Instance.GetSpeed(amendAngle); } } else { //投影不在当前线段上 } } if (amendline1 || amendline2) { _amend = amendLine1P + amendLine2P; return(true); } //对点修正 GameVector2 _outAmend1; bool _result1 = ToolGameVector.CollidePointAndCircle(_c1, _arcCen, _radius1, out _outAmend1); if (_result1) { _amend = _outAmend1; return(true); } GameVector2 _outAmend2; bool _result2 = ToolGameVector.CollidePointAndCircle(_c1, _point1, _radius1, out _outAmend2); GameVector2 _outAmend3; bool _result3 = ToolGameVector.CollidePointAndCircle(_c1, _point2, _radius1, out _outAmend3); if (_result2 || _result3) { _amend = _outAmend2 + _outAmend3; return(true); } return(false); }
/// <summary> /// 圆和正圆弧的碰撞,带位置修正 /// </summary> /// <returns><c>true</c>, if circle and arc was collided, <c>false</c> otherwise.</returns> /// <param name="_c1">圆心.</param> /// <param name="_radius1">圆半径.</param> /// <param name="_arcCen">圆弧圆心.</param> /// <param name="_arcRadius">圆弧所在圆半径.</param> /// <param name="_arcAngle">角度.</param> /// <param name="_arcAngleSize">角度范围.</param> /// <param name="_amend">修正值.</param> public static bool CollideCircleAndArc(GameVector2 _c1, int _radius1, GameVector2 _arcCen, int _arcRadius, int _arcAngle, int _arcAngleSize, out GameVector2 _amend) { _amend = GameVector2.zero; int radiusSum = _radius1 + _arcRadius; long sqrRadiusSum = radiusSum * radiusSum; long sqrDistance = _c1.sqrMagnitude(_arcCen); if (sqrDistance >= sqrRadiusSum) { return(false); } int radiusDel = _radius1 - _arcRadius; long sqrRadiusDel = radiusDel * radiusDel; if (sqrDistance <= sqrRadiusDel) { return(false); } int _angle = (_c1 - _arcCen).Angle(); int _point1Angle = _arcAngle + _arcAngleSize; int _point2Angle = _arcAngle - _arcAngleSize; bool inArc; if (_point2Angle < 0) { int _angle1 = (int)Mathf.Repeat(_angle - _point2Angle, 360f); if (_angle1 >= 0 && _angle1 <= (_point1Angle - _point2Angle)) { inArc = true; } else { inArc = false; } } else if (_point1Angle > 360) { int _delA = _point1Angle - 360; int _angle1 = (int)Mathf.Repeat(_angle - _delA, 360f); if (_angle1 >= (_point2Angle - _delA) && _angle1 <= 360) { inArc = true; } else { inArc = false; } } else { if (_angle >= _point2Angle && _angle <= _point1Angle) { inArc = true; } else { inArc = false; } } if (inArc) { //在圆弧内,需要修正 long _arcRadiusSqr = _arcRadius * _arcRadius; int distance = (int)Mathf.Sqrt(sqrDistance); int amendDis; int amendAngle; if (sqrDistance >= _arcRadiusSqr) { //向外修正 amendDis = 1 + (int)(radiusSum - distance) / 100; amendAngle = _angle; } else { amendDis = 1 + (int)(distance - Mathf.Abs(radiusDel)) / 100; amendAngle = (_arcCen - _c1).Angle(); } _amend = amendDis * BattleData.Instance.GetSpeed(amendAngle); return(true); } _point1Angle = (int)Mathf.Repeat(_point1Angle, 360); GameVector2 _point1 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point1Angle); GameVector2 _outAmend1; bool _result1 = ToolGameVector.CollidePointAndCircle(_c1, _point1, _radius1, out _outAmend1); if (_result1) { _amend = _outAmend1; return(_result1); } _point2Angle = (int)Mathf.Repeat(_point2Angle, 360); GameVector2 _point2 = _arcCen + (_arcRadius / 100) * BattleData.Instance.GetSpeed(_point2Angle); GameVector2 _outAmend2; bool _result2 = ToolGameVector.CollidePointAndCircle(_c1, _point2, _radius1, out _outAmend2); if (_result2) { _amend = _outAmend2; return(_result2); } return(false); }
public static bool IsInDistance(GameVector2 _pos1, GameVector2 _pos2, long _distance) { return(_pos1.sqrMagnitude(_pos2) <= _distance * _distance); }