gpt4 book ai didi

c++ - 圆线段碰撞 C++ (UE4)

转载 作者:行者123 更新时间:2023-11-28 04:26:44 24 4
gpt4 key购买 nike

您好,我正在尝试计算 Circle - LineSegment 碰撞(在 2D 坐标空间中)。

我想在我的代理移动时检测碰撞,所以我分步执行它的移动 -> agentPosition 是代理现在的位置,agentPosition + agentDelta 是它想要的位置参与这一步。

这条线被定义为 FVertex(是的,我知道这个名字不好)testEdge(它有 2 个点 AB).

圆被定义为以 (agentPosition + agentDelta) 为圆心,以 agentRadius 为半径。

我试图找到一个碰撞点(这将是 2 个可能的交点的平均值)并计算所需的参数:

碰撞时间 ({0.0f, 1.0f})CollisionPoint(碰撞时圆圈的位置)ImpactPoint(平均碰撞点)

这是我尝试过的方法,但我没有运气:(我得到负值或大于 1.0f 时间,有时碰撞点位于线段的另一侧和其他有趣的工件。

如果您能帮助我找出我在这里做错了什么,我将不胜感激。

static bool CheckAgentEdgeCollision(FVertex testEdge, FVector agentPosition, FVector agentDelta, float agentRadius, FCollisionResult2Dplease& outCollisionResult, UWorld* world = nullptr)
{
agentPosition.Z = 0.0f;
agentDelta.Z = 0.0f;
testEdge.B.Z = 0.0f; testEdge.A.Z = 0.0f;

FVector D = testEdge.B - testEdge.A;
FVector d = testEdge.A - (agentPosition + agentDelta);

float a = D | D; // Operator | is Dot Product
float b = (d | D) * 2.0f;
float c = (d | d) - FMath::Square(agentRadius);

float disc = b * b - 4.0f * a * c;
if (disc < KINDA_SMALL_NUMBER)
{
return false;
}

float sqrtDisc = FastSQRoot(disc);

float invA = 1.0f / ( a * 2.0f );

float t0 = (-b - sqrtDisc) * invA;
float t1 = (-b + sqrtDisc) * invA;

FVector poin1 = FVector::ZeroVector;
FVector poin2 = FVector::ZeroVector;

poin1 = testEdge.A + t0 * D;
poin2 = testEdge.A + t1 * D;

bool p1 = true;
bool p2 = true;

if(t0 > 1.0f || t0 < 0.0f)
{
//disregard
p1 = false;
}

if (t1 > 1.0f || t1 < 0.0f)
{
p2 = false;
}

if(!p1 && !p2)
{
return false;
}
else if(!p1)
{
poin1 = poin2;
}
else if (!p2)
{
poin2 = poin1;
}

float invRadius = 1.0f / agentRadius;

agentRadius += 5.0f;

//Average the points:
FVector impactPoint = (poin1 + poin2) / 2.0f;


FVector directionToCircle = agentPosition - impactPoint;
FastNormalize(directionToCircle);

FVector collisionPoint = directionToCircle * agentRadius + impactPoint;

float distToCollision = FastSQRoot(agentPosition.DistSquared2D(agentPosition, collisionPoint));
float speed = FastSQRoot(agentDelta.SizeSquared2D());

float outTime = 0.0f;
if (speed != 0.0f)
{
outTime = distToCollision / speed;
}

outCollisionResult.m_bIsPawn = false;
outCollisionResult.m_edge = testEdge;
outCollisionResult.m_normal = directionToCircle;
outCollisionResult.m_collisionPoint = collisionPoint;
outCollisionResult.m_time = outTime;
outCollisionResult.m_bHit = true;
outCollisionResult.m_impactPoint = impactPoint;

outCollisionResult.m_binPenetration = outTime < 0.0f;
return true;
}

最佳答案

提示:

如果该线段是固定的,您可以通过在给线段充气的同时“缩小”圆圈来重新解决问题,这会给您一个移动点而不是“胶囊”。如您所见,碰撞发生在中心轨迹与胶囊轮廓的交点处,可以沿着直线或圆形边缘发生。

enter image description here

通过旋转场景使线段位于 X 轴上,计算将变得更加容易。

关于c++ - 圆线段碰撞 C++ (UE4),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54127277/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com