当一个碰撞形状的多边形与碰撞形成一个圆时,我该如何检测



这是一个很难解决的问题,我已经制作了一个系统,玩家可以在屏幕上画圆圈,我希望玩家要么触摸了自己的另一条线,从那个位置开始一个新的圆圈,我的问题是不知道如何让它碰撞,我有一个想法,但不确定它是否有效,我的想法太简单了,使用一个不同的碰撞形状,在相互连接的点上创建自己,当鼠标与特定的碰撞形状碰撞时,重新开始,这是我的最佳选择,还是有其他方法可以检测圆何时形成。

这是我想要的视频:https://youtu.be/wSolVcaIszE?t=998

下面是我的视频:https://www.youtube.com/watch?v=BDnd-n3PEdQ

代码:

extends Node2D
var points_array = PoolVector2Array()
var index : int = 0
onready var collision = $Area2D/CollisionPolygon2D
func _physics_process(delta):
collision.polygon = points_array

if Input.is_action_just_pressed("Left_click"): #This sets a position so that the next line can work together
points_array.append(get_global_mouse_position()) # This makes a empty vector and the mouse cords is assigned too it
points_array.append(Vector2())
if Input.is_action_pressed("Left_click"): #This checks the distance between last vector and the mouse vector
points_array[-1] = get_global_mouse_position() # Gets the last position of the array and sets the mouse cords
if points_array[index].distance_to(get_global_mouse_position()) > 20:
points_array.append(get_global_mouse_position())
index += 1
if points_array.size() > 25: # This adds a length to the circle/line so it wont pass 18 mini lines
index -= 1
points_array.remove(0) #Removes the first array to make it look like it has a length
if Input.is_action_just_released("Left_click"): # This just clears the screen when the player releases the button
points_array = PoolVector2Array()
index = 0

假设保持点数较短。简单的线段碰撞检查就足以检测循环。

类似这样的东西:

func _segment_collision(a1:Vector2, a2:Vector2, b1:Vector2, b2:Vector2) -> bool:
# if both ends of segment b are to the same side of segment a, they do not intersect
if sign(_wedge_product(a2 - a1, b1 - a1)) == sign(_wedge_product(a2 - a1, b2 - a1)):
return false
# if both ends of segment a are to the same side of segment b, they do not intersect     
if sign(_wedge_product(b2 - b1, a1 - b1)) == sign(_wedge_product(b2 - b1, a2 - b1)):
return false
# the segments must intersect
return true
func _wedge_product(a:Vector2, b:Vector2) -> float:
# this is the length of the cross product
# it has the same sign as the sin of the angle between the vectors
return a.x * b.y - a.y * b.x

像这样使用:

if points_array.size() > 3:
for index in range(0, points_array.size() - 3):
if _segment_collision(
points_array[-1],
points_array[-2],
points_array[index],
points_array[index + 1]
):
loop(index)
break

其中loop(index)的意思是当有循环时,做任何你做的事情。


这并不是真正检测到一个圆。只是一个循环顺便说一下,参考视频也没有检测到圆圈。只是循环

您可以使用楔形产品来检查环是否是凸的。如果形状是凸的,则CCD_ 2在添加点之前和之后应该是相同的。如果它发生变化,则该形状为凹形。

对于一个圆,所有点离圆心的距离都差不多。因此,如果你检查最小和最大长度与中心的比例,你就可以测量出环的圆形程度。这个比例等于一个圆的比例。如何找到中心?你可以计算包含点的较小的轴对齐边界框(即计算点之间的最小和最大x和y坐标(,框的中心将与循环的中心匹配……假设它是对称的,如果不是,你会发现它无论如何都不是很圆,所以这很好。

相关内容

最新更新