• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >编程问答 > 2DGJK算法判断图形重叠出现的莫名其妙的bug?

2DGJK算法判断图形重叠出现的莫名其妙的bug?

作者:佚名 字体:[增加 减小] 来源:互联网 时间:2017-06-07

佚名通过本文主要向大家介绍了莫名其妙,莫名其妙的意思,女子走路莫名其妙挨打,莫名其妙的近义词,莫名其妙造句等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题:2D GJK算法判断图形重叠出现的莫名其妙的bug?
描述:

莫名其妙的意思,莫名其妙的反义词,莫名其妙tv,莫名其妙的烦躁,莫名其妙的婚姻,莫名其妙的快递,莫名其妙的名,莫名其妙的发烧,莫名其妙的诗歌,莫名其妙的头晕,莫名其妙心慌,莫名其妙的博客,莫名其妙的咳嗽,莫名其妙拉肚子,莫名其妙绝交
莫名其妙的意思,莫名其妙的反义词,莫名其妙tv,莫名其妙的烦躁,莫名其妙的婚姻,莫名其妙的快递,莫名其妙的名,莫名其妙的发烧,莫名其妙的诗歌,莫名其妙的头晕,莫名其妙心慌,莫名其妙的博客,莫名其妙的咳嗽,莫名其妙拉肚子,莫名其妙绝交

不知道这种问题拿出来问会不会不合适, 不过改了一整天都没解决... 不知道怎么描述清楚所以写得啰嗦点...

大致上是按照这个写的: http://www.dyn4j.org/2010/04/gjk-distance-closest-points/
可是即使把别人的代码抄下来也是各种bug

算法的大致描述和自己的思路是:
如果两个凸图形的闵可夫斯基差包含原点, 那么这两个图形相交
闵可夫斯基和就是把两个图形里的点都当作向量, 然后把两个图形的向量都分别相加得到一个新的图形. 闵可夫斯基差就是其中一个图形的向量都取反, 相当于绕原点反转, 然后再求闵可夫斯基和

GJK不直接求闵可夫斯基差, 而是借助下面这个函数, 每次输入一个查找方向, 然后返回闵可夫斯基差图形上距查找方向最远的一个点, 然后通过迭代生成一个个子图形, 判断子图形是否包含原点

proc getSupportPoint(s1: Sprite2D, s2: Sprite2D, dir: Vector2D): Vector2D =
    let
        invM1 = s1.invMatrix
        invM2 = s2.invMatrix
        v1 = s1.matrix * s1.graph.getFarthestPointInDirection(invM1 * dir - invM1 * Vector2D(x: 0, y: 0))
        v2 = s2.matrix * s2.graph.getFarthestPointInDirection(invM2 * dir.negate() - invM2 * Vector2D(x: 0, y: 0))
    #把查找方向变换到物体空间, 找到最远点后再变换回世界空间. 变换矩阵都只是X/Y轴上的尺寸拉伸+旋转+平移, 向量是列向量
    return v1 - v2

↓在凸多边形上找在查找方向上最远的一个点, 我的多边形顶点全是顺时针排序

method getFarthestPointInDirection*(self: Polygon, direction: Vector2D): Vector2D =
    var
        curr = self[0]
        bestProjection: float32 = curr * direction #找在dir上投影最大的那个顶点
        projection: float32

    result = curr

    for i in 1..self.len-1:
        curr = self[i]
        projection = curr * direction

        if projection > bestProjection:
            bestProjection = projection
            result = curr

↓圆形的:

method getFarthestPointInDirection*(self: Circle, direction: Vector2D): Vector2D =
    direction.norm() * self.radius #norm是求单位化向量

维基上给的GJK伪代码是:

   function GJK_intersection(shape p, shape q, vector initial_axis):
       vector  A = Support(p, initial_axis) - Support(q, -initial_axis)
       simplex s = {A}
       vector  D = -A
       loop:
           A = Support(p, D) - Support(q, -D)
           if dot(A, D) < 0:
              reject
           s = s ∪ A
           s, D, contains_origin = NearestSimplex(s)
           if contains_origin:
              accept

我的具体实现是:
假设下面的图的椭圆形是闵可夫斯基差, 小x是原点可能存在的地方, O是原点, 左边是初始状态, 右边是迭代过一次之后的状态
用(1, 0)当作初始方向找到闵可夫斯基差上的第一个顶点A, 把方向取反找到第二个顶点B
然后连线AB, 取AB的指向原点方向的垂线作为查找方向找到第三个顶点C
如果原点在ABC内, 那么判断为重叠
如果原点在绿色线的外面, 那么原点一定不在闵可夫斯基差内, 判断为不重叠
如果都不是, 就抛弃离原点最远的那个点, 用剩下的两个点作为AB, 然后继续查找C

莫名其妙的意思,莫名其妙的反义词,莫名其妙tv,莫名其妙的烦躁,莫名其妙的婚姻,莫名其妙的快递,莫名其妙的名,莫名其妙的发烧,莫名其妙的诗歌,莫名其妙的头晕,莫名其妙心慌,莫名其妙的博客,莫名其妙的咳嗽,莫名其妙拉肚子,莫名其妙绝交

proc isIntersect*(s1, s2: Sprite2D): bool =
    var
        dir = Vector2D(x: 1, y: 0)
        simplexA, simplexB, simplexC: Vector2D
        #i: int

    simplexA = getSupportPoint(s1, s2, dir)
    if simplexA * dir < 0: return false #把OA投影到方向向量上, 如果为负则原点在绿色线外, 原点一定不在闵可夫斯基差内

    dir = dir.negate()
    simplexB = getSupportPoint(s1, s2, dir)
    if simplexB * dir < 0: return false

    let
        ao = simplexA.negate()
        ab = simplexB - simplexA
    dir = tripleProduct(ab, ao, ab) #连续两次叉乘得到一个垂直于AB的贴近AO方向的向量

    while true:
        #i += 1
        #if i > 10000: assert(false)

        simplexC = getSupportPoint(s1, s2, dir)
        if simplexC * dir < 0:
            return false

        let
            ba = simplexA - simplexB
            ac = simplexC - simplexA
            bc = simplexC - simplexB
            acPerp = tripleProduct(ac, ba.negate(), ac)
            bcPerp = tripleProduct(bc, ba, bc)

        if acPerp * simplexA > 0: #把acPerp投影在ao上, 如果为负那么原点就在AC的外面
            simplexB = simplexC #此时点B离原点最远, 用点A和点C作为新的A,B
            dir = acPerp.negate()
        elif bcPerp * simplexB > 0:
            simplexA = simplexC
            dir = bcPerp.negate()
        else: return true #原点在AC和BC内, 所以原点在闵可夫斯基差内, 判断为重叠

自己觉得应该没什么问题, 但实际运行起来就会像开头的两张图那样, 经常出现"超界"的情况, 一开始以为是某些向量算出来太接近0, 但是一个个判断作特殊处理后还是完全没改善


分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • shell前面莫名其妙有了前缀……
  • 2DGJK算法判断图形重叠出现的莫名其妙的bug?

相关文章

  • 2017-06-07 表单上传能否自定义域名?
  • 2017-06-07 imageview2的文档怎么看不到了?
  • 2017-06-07 2个使用问题反馈,qrsbox遇到错误一直重试和静态资源CDN同步问题?
  • 2017-06-07 PHP解析PDF转换成在线文档
  • 2017-06-07 (python)微信:用户点击链接或者图文,会推送给服务端一个事件么?如果有怎么捕获?
  • 2017-06-07 mac上为何ssh-copy-id不好使?
  • 2017-06-07 持久化处理结果通知是否有鉴权?
  • 2017-06-07 mac外接显示器品种,大小推荐,写代码用
  • 2017-06-07 (python)安装pyspider时出错:Nospaceleftondevice:
  • 2017-06-07 python实现arp攻击

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • API接口采用HTTPS后,此时API返回的JSON是经过HTTPS加密了的吗?
    • c中构造上传凭证的时候怎么限制文件名称
    • 错错错一错再错最新版七牛SDK,打包上传报错
    • (python)django前后端分离,使用其他的模版引擎,要怎么进行配置
    • 问天问地问自己pythonimport相关问题
    • post方法参数转化成get方法拼接在url上的参数
    • mysPython3X上面使用mysqlDB问题
    • 数据从后端到浏览器在到后端的编码解码过程是如何的?
    • cocos在layer中添加button和textField时为何不能显示
    • 拼音搜索如何实现?

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有