Unity判断平面坐标是否在范围圆(包括椭圆)内

【前言】

前段时间,做地面雷达投影项目,有这么个需求,需要在画面的圆中才能交互出特效,思索了几天,弄了几种圆内的判断方案,分享一下。
在这里插入图片描述

配图:1.0版本雷达项目截图,需要在圆中交互,右中上闪动的点为交互生成特效

【方案梳理】建议用方案2,简单代码少

【方案1简介】

最初做的基于圆内(不是椭圆),作等边三角形(类似于等边三角形的外接圆),然后用检测的点和圆上三个点传递进方法里做算法,以下见代码。
在这里插入图片描述
配图:圆上取ABC三点作等边三角形,A点坐标(圆心x,圆心y+上半径y),B点坐标(左半径中点的x,下半径中点的y),C点坐标(右半径中点的x,下半径中点的y)

【放出代码】

做法参照CSDN帖子(https://blog.csdn.net/mrbaolong/article/details/48227685)改的C#代码

/// <summary>
    /// 如果点(p)位于由三角形(p1,p2,p3)组成的圆周内,则返回true
    /// </summary>
    /// <remarks>
    ///注意:边缘上有一个点在外圈内
    /// </remarks>
    /// <param name="p">检测的点</param>
    /// <param name="p1">圆上的第一点</param>
    /// <param name="p2">圆上的第二点</param>
    /// <param name="p3">圆上的第三点</param>
    /// <returns>如果p在圆内,则为真</returns>
    private static bool InCircle(Vector2 p, Vector2 p1, Vector2 p2, Vector2 p3)
    {
        //Return TRUE if the point (xp,yp) lies inside the circumcircle
        //made up by points (x1,y1) (x2,y2) (x3,y3)
        //NOTE: A point on the edge is inside the circumcircle

        if (System.Math.Abs(p1.y - p2.y) < double.Epsilon && System.Math.Abs(p2.y - p3.y) < double.Epsilon)
        {
            //INCIRCUM - F - Points are coincident !!
            return false;
        }

        double m1, m2;
        double mx1, mx2;
        double my1, my2;
        double xc, yc;

        if (System.Math.Abs(p2.y - p1.y) < double.Epsilon)
        {
            m2 = -(p3.x - p2.x) / (p3.y - p2.y);
            mx2 = (p2.x + p3.x) * 0.5;
            my2 = (p2.y + p3.y) * 0.5;
            //Calculate CircumCircle center (xc,yc)
            xc = (p2.x + p1.x) * 0.5;
            yc = m2 * (xc - mx2) + my2;
        }
        else if (System.Math.Abs(p3.y - p2.y) < double.Epsilon)
        {
            m1 = -(p2.x - p1.x) / (p2.y - p1.y);
            mx1 = (p1.x + p2.x) * 0.5;
            my1 = (p1.y + p2.y) * 0.5;
            //Calculate CircumCircle center (xc,yc)
            xc = (p3.x + p2.x) * 0.5;
            yc = m1 * (xc - mx1) + my1;
        }
        else
        {
            m1 = -(p2.x - p1.x) / (p2.y - p1.y);
            m2 = -(p3.x - p2.x) / (p3.y - p2.y);
            mx1 = (p1.x + p2.x) * 0.5;
            mx2 = (p2.x + p3.x) * 0.5;
            my1 = (p1.y + p2.y) * 0.5;
            my2 = (p2.y + p3.y) * 0.5;
            //Calculate CircumCircle center (xc,yc)
            xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
            yc = m1 * (xc - mx1) + my1;
        }

        double dx = p2.x - xc;
        double dy = p2.y - yc;
        double rsqr = dx * dx + dy * dy;
        //double r = Math.Sqrt(rsqr); //外接圆半径
        dx = p.x - xc;
        dy = p.y - yc;
        double drsqr = dx * dx + dy * dy;

        return (drsqr <= rsqr);
    }

【方案2简介】

在这里插入图片描述
上图中x0和y0是检测点相对于圆心的x,y坐标,a,b分别是椭圆的长半径和短半径,参照点在圆内的计算公式就能写出算法,以下见代码。
在这里插入图片描述
配图:为网图,仅作参照

【放出代码】

 /// <summary>
 /// 判断点在圆内
 /// </summary>
 /// <param name="point">检测的点</param>
 /// <param name="centerPoint">圆心点</param>
 /// <param name="x">x的半径长</param>
 /// <param name="y">y的半径</param>
 /// <returns></returns>
 private bool inOval(Vector2 point, Vector2 centerPoint, float x, float y)
 {
     double v = Mathf.Pow(centerPoint.x - point.x, 2) / Mathf.Pow(x, 2) + Mathf.Pow(centerPoint.y - point.y, 2) / Mathf.Pow(y, 2);
     return v < 1;
 }

【最后想说】

最近去鹅厂做UE4客户端,也正在适应Unity转UE4这个过程,过段时间会分享一些相关的心得,也是很久没更新文章了,所以借此时机,再更新一些之前对Unity使用的一些技巧,请多多支持鸭。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值