首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >检查两条线是否相交

检查两条线是否相交
EN

Stack Overflow用户
提问于 2018-10-10 18:25:34
回答 3查看 1.4K关注 0票数 0

我要检查两条线是否相交。这些当前被包裹在边缘对撞器中。

在我的最小示例中,我使用了Collider2D.OverlapsCollider

代码语言:javascript
运行
AI代码解释
复制
public class EdgeColliderChecker : MonoBehaviour
{
    public EdgeCollider2D e1;
    public EdgeCollider2D e2;

    void Update () {
        Collider2D[] results1 = new Collider2D[1];
        e1.OverlapCollider(new ContactFilter2D(), results1);
        if (results1[0] != null)
        {
            Debug.Log(results1[0].name);
        }

        Collider2D[] results2 = new Collider2D[1];
        e1.OverlapCollider(new ContactFilter2D(), results2);
        if (results2[0] != null) {
            Debug.Log(results2[0].name);
        }
    }
}

这是我设置场景的方式:

正如你在上面的图片中看到的,这两条线显然是相交的。

问题是没有任何东西输出到控制台。

我不是百分之百确定ContactFilter应该如何配置,但看看文档,它是用来过滤结果的。因此,将其保留为空应该包括所有内容。

我真的只需要在两行之间进行检查。因此,将它们作为参数并返回指示交集的布尔值的函数将是最方便的。不幸的是,我在Unity中找不到这样的函数。

我自己构造函数应该不会太复杂,但我更喜欢使用unity提供的函数。因此,与其说这是一个与数学有关的问题,不如说是一个与统一性有关的问题。

编辑:

使用Collider2D.IsTouching(Collider2D)似乎也不起作用。我使用与前面相同的设置来代替下面的代码:

代码语言:javascript
运行
AI代码解释
复制
public class EdgeColliderChecker : MonoBehaviour
{
    public EdgeCollider2D e1;
    public EdgeCollider2D e2;

    void Update () {
        if (e1.IsTouching(e2)) {
            Debug.Log("INTERSECTION");
        }
    }
}

编辑2:

为此,我尝试创建自己的方法:

代码语言:javascript
运行
AI代码解释
复制
public static class EdgeColliderExtentions {
    public static List<Collider2D> GetInterSections(this EdgeCollider2D collider)
    {
        List<Collider2D> intersections = new List<Collider2D>();
        Vector2[] points = collider.points;
        for (int i = 0; i < points.Length - 1; i++)
        {
            Vector2 curr = collider.transform.TransformPoint(points[i]);
            Vector2 next = collider.transform.TransformPoint(points[i + 1]);
            Vector2 diff = next - curr;

            Vector2 dir = diff.normalized;

            float distance = diff.magnitude;

            RaycastHit2D[] results = new RaycastHit2D[30];
            ContactFilter2D filter = new ContactFilter2D();

            Debug.DrawLine(curr, curr + dir * distance, Color.red, 1 / 60f);

            int hits = Physics2D.Raycast(curr, dir, filter, results, distance);

            for (int j = 0; i < hits; i++)
            {
                Collider2D intersection = results[j].collider;
                if (intersection != collider)
                {
                    intersections.Add(intersection);
                }
            }
        }
        return intersections;
    }
}

EdgeColliderChecker

代码语言:javascript
运行
AI代码解释
复制
public class EdgeColliderChecker : MonoBehaviour
{
    public EdgeCollider2D e1;

    void Update ()
    {
        List<Collider2D> hits = e1.GetInterSections();
        if (hits.Count > 0) {
            Debug.Log(hits.Count);
        }
    }
}

还是一无所获。即使我计算的点与对撞机完全一致:

我为它做了数学计算,它似乎工作得很好,但测试不是很彻底。如果交叉点检查是在碰撞机四处移动时运行的,则交叉点检查会有一点起伏:

代码语言:javascript
运行
AI代码解释
复制
public class Line {
    private Vector2 start;
    private Vector2 end;

    public Line(Vector2 start, Vector2 end)
    {
        this.start = start;
        this.end = end;
    }

    public static Vector2 GetIntersectionPoint(Line a, Line b)
    {
        //y = kx + m;
        //k = (y2 - y1) / (x2 - x1)
        float kA = (a.end.y - a.start.y) / (a.end.x - a.start.x);
        float kB = (b.end.y - b.start.y) / (b.end.x - b.start.x);

        //m = y - k * x
        float mA = a.start.y - kA * a.start.x;
        float mB = b.start.y - kB * b.start.x;

        float x = (mB - mA) / (kA - kB);
        float y = kA * x + mA;
        return new Vector2(x,y);
    }

    public static bool Intersects(Line a, Line b)
    {
        Vector2 intersect = GetIntersectionPoint(a, b);            

        if (Vector2.Distance(a.start, intersect) < Vector2.Distance(a.start, a.end) &&
            Vector2.Distance(a.end, intersect) < Vector2.Distance(a.start, a.end))
        {
            return true;
        }
        return false;
    }
}

public static class EdgeColliderExtentions
{
    public static bool Intersects(this EdgeCollider2D collider, EdgeCollider2D other)
    {
        Vector2[] points = collider.points;
        Vector2[] otherPoints = other.points;
        for (int i = 0; i < points.Length - 1; i++)
        {
            Vector2 start = collider.transform.TransformPoint(points[i]);
            Vector2 end = collider.transform.TransformPoint(points[i + 1]);
            Line line = new Line(start, end);
            for (int j = 0; j < otherPoints.Length - 1; j++)
            {
                Vector2 otherStart = other.transform.TransformPoint(otherPoints[i]);
                Vector2 otherEnd = other.transform.TransformPoint(otherPoints[i + 1]);
                Line otherLine = new Line(otherStart, otherEnd);
                if (Line.Intersects(line, otherLine))
                {
                    return true;
                }
            }
        }
        return false;
    }
}

但是我真的很想用unity提供的东西来代替。

EN

回答 3

Stack Overflow用户

发布于 2018-10-10 18:41:28

使用Collider.bounds.Intersects(Collider.bounds)确定两个边界是否相交:

代码语言:javascript
运行
AI代码解释
复制
void Update () {
    if (e1.bounds.Intersects(e2.bounds)) {
        Debug.Log("Bounds intersecting");
    }
}

不幸的是,这不会让你知道边缘是否相交。但是,如果测试结果为假,则可以跳过边缘测试。

票数 1
EN

Stack Overflow用户

发布于 2018-10-11 22:52:05

我意识到我可以根据我的用例将其中一个边缘对撞器交换为多边形对撞器。

Collider2D.OverlapsCollider()中使用多边形和边碰撞器可以按预期工作。

我不知道我是否应该接受这个答案,因为它没有解决最初的问题,即在单位中寻找直线相交的函数。

票数 1
EN

Stack Overflow用户

发布于 2018-10-12 06:01:36

您可以使用以下内容获得相对接近的近似结果:

你可以创建一个脚本,沿着这条线均匀地添加几个小盒子碰撞器,越多越好。然后进行正常的碰撞检测。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52746588

复制
相关文章
flask 使用sendgrid发送邮件(flask 33)
import sendgrid from sendgrid.helpers.mail import Email as SGEmail, Content, Mail as SGMail from flask_mail import Mail, Message from flask_wtf import FlaskForm from wtforms import StringField, TextAreaField, SubmitField from wtforms.validators import DataRequired, Email from flask import Flask, flash, redirect, url_for, render_template, request
用户5760343
2019/08/13
8470
Linux下使用Shell为SendGrid Email API 发送邮件
将代码存为shell文件,将上一个文件的echo输出改成执行此文件即可自动推送到邮箱。
子润先生
2021/06/14
1.1K0
使用 PHP发送电子邮件
PHP 运行邮件函数需要一个已安装且正在运行的邮件系统(如:sendmail、postfix、qmail等)。所用的程序通过在 php.ini 文件中的配置设置进行定义。
小颖club
2022/04/11
2.6K0
python利用flask_mail、sendgrid发送邮件[通俗易懂]
在学习Flask,看的书籍是《Flask Web开发实战 入门、进阶与原理解析》。在学习发送电子邮件这一章节时,遇到一些问题,便写下这一篇文章,记录一下,也希望遇到同样问题的人能够花较少时间在解决问题上。
全栈程序员站长
2022/11/17
1.8K0
python利用flask_mail、sendgrid发送邮件[通俗易懂]
PHP 使用 phpmailer 发送电子邮件
phpMailer 是一个非常强大的 ph p发送邮件类,可以设定发送邮件地址、回复地址、邮件主题、html网页,上传附件,并且使用起来非常方便。
OwenZhang
2021/12/08
2.2K0
PHP 使用 phpmailer 发送电子邮件
使用Python发送自定义电子邮件
电子邮件仍然是事实。 尽管存在各种弊端,但它仍然是向大多数人发送信息的最佳方法,特别是允许邮件排队等待收件人的自动方式。
用户7886150
2021/01/28
2.9K0
发送电子邮件
在即时通信软件如此发达的今天,电子邮件仍然是互联网上使用最为广泛的应用之一,公司向应聘者发出录用通知、网站向用户发送一个激活账号的链接、银行向客户推广它们的理财产品等几乎都是通过电子邮件来完成的,而这些任务应该都是由程序自动完成的。
用户8442333
2021/05/20
2.4K0
.NET Core 使用MailKit发送电子邮件
发送邮件通知的功能在各种系统里都很常见。我的博客也能在有新评论、新回复,或者文章被其他网站引用时向管理员发送邮件。那么在.NET Core里,如何实现发送电子邮件呢?
Edi Wang
2019/07/08
6.1K0
.NET Core 使用MailKit发送电子邮件
SpringBoot发送邮件+使用html模板发送邮件
这两天在公司做商城系统有一个业务用到了发送邮件功能 springboot 有spring-boot-starter-mail
@依然范特西
2022/12/12
3K0
使用Postfix,Dovecot和MySQL发送电子邮件
在本指南中,您将学习如何在Debian或Ubuntu上使用Postfix,Dovecot和MySQL设置安全的虚拟用户邮件服务器。我们将解释如何创建新的用户邮箱以及如何在配置的域中发送或接收电子邮件。
Techeek
2018/09/18
3.9K0
使用Postfix,Dovecot和MySQL发送电子邮件
Spring发送电子邮件
Spring基于javax.mail封装了一套用于发送电子邮件的API,位于org.springframework.mail包下,下面将介绍下发送普通文本邮件和基于thymeleaf模版的邮件。
布禾
2020/10/29
1.8K0
Spring发送电子邮件
Jenkins使用之邮件模板配置
Jenkins默认提供了一个邮件通知,能在构建失败、构建不稳定等状态后发送邮件。但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容、无法定义发送邮件的格式、无法定义灵活的邮件接收配置等。为解决这些问题,我们将使用 Email Extension 插件。该插件可以自定义邮件通知,如在发送邮件时自定义发送给谁以及具体内容等。本文主要对jenkins的邮件模板配置及通知进行介绍。
用户5521279
2020/03/19
4.5K0
Jenkins使用之邮件模板配置
SpringBoot使用FreeMarker模板发送邮件
由于本文属于付费文章,获取全文,可点击文末【阅读原文】,即可到达【秋码记录】https://qiucode.cn/article/96 1、添加相关依赖 1.1、使用Maven,在pom.xml添加如下依赖: <!-- 邮件所需依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!--
游离于山间之上的Java爱好者
2022/12/19
1.4K0
SpringBoot使用FreeMarker模板发送邮件
PHP 使用 phpmailer 发送电子邮件 以及封装方法
phpMailer 是一个非常强大的 ph p发送邮件类,可以设定发送邮件地址、回复地址、邮件主题、html网页,上传附件,并且使用起来非常方便。
Inkedus
2020/04/16
3.4K0
PHP 使用 phpmailer 发送电子邮件 以及封装方法
Spring Boot发送电子邮件
通过使用Spring Boot RESTful Web服务,可以发送包含Gmail传输层安全性的电子邮件。在本章中,详细了解如何使用此功能。
黑洞代码
2021/10/14
1.4K0
Elasticsearch索引模板与动态mapping模板(四)
前面我们介绍了mapping相关的属性,细心的朋友可能会发现,在我们最开始使用ES的时候,可能还不太了解mapping,也没有添加过mapping为什么我们还是能够正常的添加文档。
问道白发
2019/12/15
5.1K0
Elasticsearch索引模板与动态mapping模板(四)
PHP发送电子邮件代码
注意:PHP 需要一个已安装且正在运行的邮件系统,以便使邮件函数可用。所用的程序通过在 php.ini 文件中的配置设置进行定义。
用户1503405
2021/09/27
1.8K0
如何在FreeBSD 10.1上使用Sendmail通过外部SMTP服务发送电子邮件
设置新的Web服务器时最常见的需求之一是发送电子邮件。最安全,最简单的方法是将服务器连接到SendGrid或Amazon SES等邮件服务。使用外部服务将帮助您避免陷阱,例如您的服务器IP被反垃圾邮件服务列入黑名单。
温浪
2018/10/19
3.2K0
点击加载更多

相似问题

使用sendgrid节点模块,如何发送SendGrid模板引擎电子邮件?

23

使用csv的数据与Sendgrid一起发送电子邮件

19

发送没有模板的Sendgrid电子邮件

17

如何在python中使用sendgrid和动态模板、BCC地址发送电子邮件?

110

Sendgrid:用模板发送电子邮件

23
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档