Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Collision detection 点-方碰撞后的滑动响应_Collision Detection_Game Physics - Fatal编程技术网

Collision detection 点-方碰撞后的滑动响应

Collision detection 点-方碰撞后的滑动响应,collision-detection,game-physics,Collision Detection,Game Physics,在一般术语和伪代码中,如果墙实际上只是一个点碰撞到的整个正方形的一部分,那么沿着墙滑动的碰撞响应的最佳方式是什么?使用的碰撞测试方法是一种测试,以查看点是否位于正方形中 我是否应该将正方形分成四条线,然后计算到该线的最短距离,然后将点移回该距离?如果是,那么如何确定碰撞后该点最靠近正方形的哪条边?通过测试墙壁上的运动向量来检测碰撞点。如果您知道有关曲面的信息(例如,您所说的曲面是长方体的一部分),则可以同时测试多个墙 二维和三维之间的解决方案可能略有不同。我会选择2D,因为你说的是“正方形”,而

在一般术语和伪代码中,如果墙实际上只是一个点碰撞到的整个正方形的一部分,那么沿着墙滑动的碰撞响应的最佳方式是什么?使用的碰撞测试方法是一种测试,以查看点是否位于正方形中


我是否应该将正方形分成四条线,然后计算到该线的最短距离,然后将点移回该距离?如果是,那么如何确定碰撞后该点最靠近正方形的哪条边?

通过测试墙壁上的运动向量来检测碰撞点。如果您知道有关曲面的信息(例如,您所说的曲面是长方体的一部分),则可以同时测试多个墙

二维和三维之间的解决方案可能略有不同。我会选择2D,因为你说的是“正方形”,而不是“立方体”或“盒子”

一旦你知道你的点击中的地方,你就可以得到你的运动向量的剩余部分,沿着墙的方向点它(从墙上的一个点减去另一个点,然后标准化),然后按这个量缩放墙的方向。假设没有摩擦力,这是平行于墙的运动量

编辑添加了以下代码:

样板:

import math

class Vector2d:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, rhs):
        return Vector2d(self.x + rhs.x, self.y + rhs.y)

    def __sub__(self, rhs):
        return Vector2d(self.x - rhs.x, self.y - rhs.y)

    def GetScaled(self, scale):
        return Vector2d(self.x * scale, self.y * scale)

    def GetLength(self):
        return math.sqrt((self.x * self.x) + (self.y * self.y))

    def GetNormalized(self):
        return self.GetScaled(1.0 / self.GetLength())

def DotProduct(v0, v1):
    return (v0.x * v1.x) + (v0.y * v1.y)
真正的业务:

class Wall2d:
    def init(self, point0, point1):
        """point0, point1 are Vector2ds"""
        self.p0 = point0
        self.p1 = point1

        # these three steps could be combined to optimize, but
        # for demonstration are left explicit
        self.dir = self.p1 - self.p0
        self.length = self.dir.GetLength()
        self.dir = self.dir.GetNormalized()

        # computing the normal in 3D would require three points
        # on the face and a cross product
        self.normal = Vector2d(self.length.y, -self.length.x)

    def LineSegmentCollides(self, pointStart, pointEnd):
        startDot = DotProduct(pointStart - self.p0, self.normal)
        endDot = DotProduct(pointEnd - self.p0, self.normal)
        if startDot * endDot < 0:
            # the only way a collision can occur is if the start
            # and end are on opposite sides of the wall, so their
            # dot product results will have opposite signs, so
            # the result of the multiplication is negative
            moveVector = pointEnd - pointStart

            # scale the movement vector by the ratio of the move
            # vector on the "start" side versus the total length
            # of the movement in the axis of the normal
            collisionDelta = moveVector.GetScaled(startDot /
                                                  (startDot + endDot))
            collisionPoint = pointStart + collisionDelta

            collisionDot = DotProduct(collisionPoint - self.p0, self.dir)
            if (collisionDot > 0) && (collisionDot < self.length):
                # we've hit the wall between p0 and p1 (other
                # values of collisionDot mean we missed on one
                # end or the other)

                # now, collision response is up to you.  In this
                # case, we'll just zero out the movement in the
                # direction of the wall after the collision
                # (sorry about the poor naming)
                # note that we don't actually care about the actual
                # point of collision here.
                collisionPushBack = moveVector.GetScaled(
                                         endDot / (startDot + endDot))
                endPoint = pointEnd + collisionPushBack

                return True
        return False
class Wall2d:
def初始化(自身、点0、点1):
“”“点0、点1是矢量2D”“”
self.p0=0点
self.p1=点1
#这三个步骤可以结合起来进行优化,但是
#对于演示,它们是显式的
self.dir=self.p1-self.p0
self.length=self.dir.GetLength()
self.dir=self.dir.GetNormalized()
#在3D中计算法线需要三个点
#关于面和叉积
self.normal=Vector2d(self.length.y,-self.length.x)
def LineSegments碰撞(自、点开始、点结束):
startDot=DotProduct(pointStart-self.p0,self.normal)
endDot=DotProduct(pointEnd-self.p0,self.normal)
如果开始点*结束点<0:
#发生碰撞的唯一方法是
#末端在墙的两侧,所以
#点积结果将有相反的符号,所以
#乘法的结果是负数
moveVector=点结束-点开始
#按移动的比率缩放移动向量
#“开始”侧的矢量与总长度
#在法线轴上的运动
collisionDelta=moveVector.GetScaled(startDot/
(开始点+结束点)
碰撞点=点起点+碰撞增量
碰撞点=点积(碰撞点-self.p0,self.dir)
如果(碰撞点>0)&(碰撞点<自身长度):
#我们碰到了p0和p1之间的墙(其他
#collisionDot的值意味着我们错过了一个
#(结束或其他)
#现在,碰撞响应取决于您。在这个
#如果是这样的话,我们只需要在
#碰撞后墙的方向
#(很抱歉命名错误)
#请注意,我们实际上并不关心实际情况
#这里是碰撞点。
collisionPushBack=moveVector.GetScaled(
结束点/(开始点+结束点))
端点=点端点+碰撞回推
返回真值
返回错误
我希望这是有用的