微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我如何能够检测到碰撞形状多边形何时形成了一个带有碰撞的圆

如何解决我如何能够检测到碰撞形状多边形何时形成了一个带有碰撞的圆

这是一个很难提出问题的想法,我制作了一个玩家在屏幕上画圆圈的系统,我希望玩家触摸了自己的另一条线,从那个位置开始一个新的圆圈,这个问题我我不知道如何让它发生碰撞,我有一个想法但不确定它是否会起作用,我的想法太简单地使用不同的碰撞形状,在相互连接的点上以及鼠标与那个特定的碰撞形状再次开始碰撞,这是我拥有的最佳选择还是有另一种检测何时形成圆形的方法

这是我想要的视频: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) 表示在有循环时执行任何操作。


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

您可以使用楔形乘积检查循环是否为凸形。如果形状是凸的 sign(_wedge_product(points_array[-1] - points_array[-2],points_array[-2] - points_array[-3])) 在添加一个点之前和之后应该是相同的。如果它改变了,那么形状就是凹的。

对于圆,所有点到中心的距离大致相同。因此,如果您检查到中心的最小和最大长度之间的比例,您就可以衡量循环的圆形程度。一个圆的比例将等于 1。如何找到中心?您可以计算包含点的较小轴对齐的边界框(即计算跨点的最小和最大 x 和 y 坐标),并且框的中心将匹配循环的中心......假设它是对称的,如果它不是,反正你会发现它不是很圆,所以没关系。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。