【发布时间】:2017-09-20 03:05:22
【问题描述】:
使用 moveto 和 lineto 在窗口画布上绘制各种线条...
在运行时确定对象(如位图或图片控件)是否与使用 lineto 绘制的线“接触”(相同的 x,y 坐标)的最简单方法是什么在窗口画布上?
一个简单的例子是一个球(位图或图片)“接触”绘制的边框并反弹......了解对象、图片或位图与任何存在的线之间是否发生“接触”的最简单方法是什么在窗户上?
【问题讨论】:
标签: c++ bitmap c++builder
使用 moveto 和 lineto 在窗口画布上绘制各种线条...
在运行时确定对象(如位图或图片控件)是否与使用 lineto 绘制的线“接触”(相同的 x,y 坐标)的最简单方法是什么在窗口画布上?
一个简单的例子是一个球(位图或图片)“接触”绘制的边框并反弹......了解对象、图片或位图与任何存在的线之间是否发生“接触”的最简单方法是什么在窗户上?
【问题讨论】:
标签: c++ bitmap c++builder
如果我做对了,您希望在移动时在圆形物体和线之间进行碰撞检测/避免。我知道有更多的选择可以做到这一点......
向量方法
您还需要记住所有以矢量形式渲染的东西,因此您需要所有渲染线、对象等的列表......然后对于特定对象循环遍历所有其他对象,并使用矢量数学以代数方式检查碰撞。就像检测边界框之间的交叉点,然后检测特定的线/折线/多边形或其他任何东西。
光栅方法
这更容易实现,有时甚至更快但不太准确(仅像素精度)。这个想法是用背景颜色清除对象的最后位置。然后检查将在新位置渲染的所有像素,如果不存在其他背景颜色,则不会发生碰撞,因此您可以渲染像素。如果存在任何非背景颜色,则在发生碰撞时再次将对象渲染到原始位置。
您还可以在新旧位置之间进行检查,并将对象放在第一个非碰撞位置,这样您就更靠近边缘...
这种方法需要快速的像素访问,否则会太慢。如果不使用 GDI 中的 BitBlt,标准 Canvas 不允许这样做。幸运的是,VCL GRaphics::TBitmap 具有ScanLine[] 属性,如果使用得当,可以直接访问像素而不会影响性能。请参阅我回答的其他问题中的示例:
访问ScanLine[y][x] 和Pixels[x][y] 一样慢,但是您可以将所有指向位图每一行的指针存储一次,然后使用它来代替,这与访问您自己的二维数组相同。所以你真的只需要位图->高度调用ScanLine[y] 在位图的任何调整大小或分配之后进行整个图像渲染......
如果你有基于图块的场景,你可以在图块上使用这种方法而不是像这样的像素:
现场方法
这也被认为是一种矢量方法,但不需要碰撞检查。相反,每个物体都会产生排斥力,距离它越近,排斥力就会被添加到牛顿/达朗伯物理驱动力中。当系数设置正确时,它将自行避免碰撞。这也用于自动放置物品等...有关更多信息,请参阅:
混合方法
您可以将上述任何方法组合在一起,以更好地满足您的需求。例如参见:
【讨论】: