当前位置:网站首页>Unity3d: vector calculation, AOE graph intersection
Unity3d: vector calculation, AOE graph intersection
2022-07-23 12:53:00 【Sixi Liyu】
The shortest distance to the point of a straight line
/// <summary>
/// Trigonometric function method x The straight line x0 As a starting point ,u Is the square of the vertical shortest distance of the unit vector
/// </summary>
/// <param name="x0"> The starting point </param>
/// <param name="u"> The unit vector of the ray </param>
/// <param name="x"></param>
/// <returns></returns>
public static float StraightPointSqrMinDistanceByDir(Vector2 x0, Vector2 u, Vector2 x)
{
float t = Vector2.Dot(x - x0, u);
return (x - (x0 + Mathf.Abs(t) * u)).sqrMagnitude;
}
x0 As a starting point ,u Is the unit vector , be x0t The length of is |x0x|cosa = x0xu / |u|, because u Is the unit vector , The mold length is 1. Then get t The coordinates of the points are x - (x0 + Mathf.Abs(t) * u), because x May be in x0 Left side , So only the absolute value of length Unit vector , And then calculate x,t Two point distance 
The distance between a point and a line segment
The shortest vertical distance is when the point falls between line segments , Otherwise, it is the shortest distance to one of the two endpoints
/// <summary>
/// Calculate the square distance between the line segment and the point , The point is the vertical distance between line segments , Otherwise, it is the distance from the nearest endpoint
/// </summary>
/// <param name="x0"></param>
/// <param name="u"> Line direction to the end , Subtract two points </param>
/// <param name="x"></param>
/// <returns></returns>
public static float SegmentPointSqrDistance(Vector2 x0, Vector2 u, Vector2 x)
{
float t = Vector2.Dot(x - x0, u) / u.sqrMagnitude;
return (x - (x0 + Mathf.Clamp(t, 0, 1) * u)).sqrMagnitude;
}
1、 First, suppose you know two points on a straight line P1、P2、 And a point outside the straight line P3.
2、 Let the projection point be P0.
3、 because P0、P1、P2 All in the same straight line , So you can get it. k (P2 - P1) = P0 - P1
k = |P0-P1|/|P2-P1|. Just find the scale factor k, Then we can find out P0 Value .
4、 Make v1 = P3 - P1 , v2 = P2 - P1,v1 And v2 Point multiplication is :v1v2=cos(seta)|P3-P1||P2-P1|=|P0-P1||P2-P1|, therefore
k = |P0-P1|/|P2-P1| = ( (v1v2)/|P2-P1| ) / |P2-P1| = (P3 - P1) * (P2 - P1) / (|P2 - P1| * |P2 - P1|)
Because it is the distance to the line segment , therefore k For the range of [0,1], Projection point coordinates x0 + Mathf.Clamp(t, 0, 1) * u ,u by x1 - x0
Whether the point is in the rectangle
Exoproduct , Also known as cross product , It's vector algebra ( Analytic geometry ) A concept in . Two vectors v1(x1, y1) and v2(x2, y2) Outer product of v1×v2=x1y2-y1x2. If by v1 To v2 It turns clockwise , The outer product is negative , The opposite is positive , by 0 It means that the two directions are the same ( parallel ).
// Exoproduct . Two vectors v1(x1, y1) and v2(x2, y2) Outer product of v1×v2=x1y2-y1x2.
//>0,a stay b clockwise <0,a stay b Anti-clockwise
public static float Cross(this Vector2 a, Vector2 b)
{
return a.x * b.y - b.x * a.y;
}
public static bool IsPointInRectangle(Vector2 P, Vector2[] rectCorners)
{
return IsPointInRectangle(P, rectCorners[0], rectCorners[1], rectCorners[2], rectCorners[3]);
}
// rectangular 4 A little bit , Sort counterclockwise or clockwise from the first point
public static bool IsPointInRectangle(Vector2 P, Vector2 A, Vector2 B, Vector2 C, Vector2 D)
{
Vector2 AB = A - B;
Vector2 AP = A - P;
Vector2 CD = C - D;
Vector2 CP = C - P;
Vector2 DA = D - A;
Vector2 DP = D - P;
Vector2 BC = B - C;
Vector2 BP = B - P;
bool isBetweenAB_CD = AB.Cross(AP) * CD.Cross(CP) > 0;
bool isBetweenDA_BC = DA.Cross(DP) * BC.Cross(BP) > 0;
return isBetweenAB_CD && isBetweenDA_BC;
}
Circles intersect
The distance between the centers of two circles is square < Both radii are square
Circle intersects rectangle
/// <summary>
/// Whether the circle intersects with the rectangle
/// </summary>
/// <param name="cc"> center of a circle </param>
/// <param name="r"> Circle radius </param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <param name="d"></param>
/// <returns></returns>
public static bool IsCicleRectIntersect(Vector2 cc,float r,Vector2 rectA,Vector2 rectB, Vector2 rectC, Vector2 rectD)
{
if (IsPointInRectangle(cc, rectA, rectB, rectC, rectD))// The center of the circle is inside the rectangle
{
return true;
}
else// The center of the circle is outside the rectangle , Intersect with any edge , That is, intersection
{
float sqR = r * r;
float disA = SegmentPointSqrDistance(rectA, rectB - rectA, cc);
if (disA < sqR)
{
return true;
}
float disB = SegmentPointSqrDistance(rectB, rectC - rectB, cc);
if (disB < sqR)
{
return true;
}
float disC = SegmentPointSqrDistance(rectC, rectD - rectC, cc);
if (disC < sqR)
{
return true;
}
float disD = SegmentPointSqrDistance(rectD, rectA - rectD, cc);
if (disD < r * r)
{
return true;
}
}
return false;
}
The center of the circle intersects in the rectangle . The center of the circle is outside the rectangle , Compare the distance from the center of the circle to each rectangular edge segment , As long as there is one < The radius of the circle intersects
Coordinates after the point rotates around another point
Angle between two vectors
float angel = Vector2.Angle(Vector2.right, dirPos);
if (dirPos.y < 0)
{
angel = -angel;
}
A vector and Vector.right The angle between
Vector2.Angle
First quadrant :0~90
Beta Quadrant :90~180
The third quadrant :180~90
Quadrant four :90~0
The third and fourth quadrants should be Negative rotation
Coordinates after rotation
public static Vector2 RotatePoint(Vector2 origin, float angle, Vector2 point)
{
// Translate point back to origin;
Vector2 temp = new Vector2(point.x -= origin.x, point.y -= origin.y);
// Roate the point
float xNew = Mathf.Cos(angle * Mathf.Deg2Rad) * (point.x) - Mathf.Sin(angle * Mathf.Deg2Rad) * (point.y);
float yNew = Mathf.Cos(angle * Mathf.Deg2Rad) * (point.y) + Mathf.Sin(angle * Mathf.Deg2Rad) * (point.x);
temp.x = xNew + origin.x;
temp.y = yNew + origin.y;
return temp;
}
The circle intersects with the facing rectangle
First use rect The rectangular , Then rotate according to the rectangle towards the vector rect Four vertices of
// No rotation towards rectangle -----> The server is a rectangle centered on the selection point , The client selection point is at the edge of the rectangle ,unity in rect Direction cannot be used
Rect effRange = new Rect(selectedPos.x, selectedPos.y - rectHigh * .5f, rectWidth, rectHigh);
Vector2 pos1 = HXUtility.RotatePoint(selectedPos, angel, effRange.min);
Vector2 pos2 = HXUtility.RotatePoint(selectedPos, angel, effRange.min + new Vector2(effRange.width, 0));
Vector2 pos3 = HXUtility.RotatePoint(selectedPos, angel, effRange.min + new Vector2(0, effRange.height));
Vector2 pos4 = HXUtility.RotatePoint(selectedPos, angel, effRange.max);
Then judge whether the point intersects with the rectangle
The circle intersects with the facing sector
// Intersection test of sector and disc
// a Sector center
// u Sector direction ( Unit vector )
// theta Sector sweep half angle
// l Sector side length
// c Disc center
// r Radius of disc
public static bool IsCicleSectorIntersect(
Vector2 a, Vector2 u, float theta, float l,
Vector2 c, float r)
{
// 1. If the direction of the sector center and the disc center can be separated , The two shapes do not intersect
Vector2 d = c - a;
float rsum = l + r;
if (d.sqrMagnitude > rsum * rsum)
return false;
// 2. Calculate the fan-shaped local space p
float px = Vector2.Dot(d, u);
float py = Mathf.Abs(Vector2.Dot(d, new Vector2(-u.y, u.x)));// Sector unit direction vector rotates counterclockwise 90 degree
// 3. If p_x > ||p|| cos theta, Two shapes intersect
if (px > d.magnitude * Mathf.Cos(theta * Mathf.Deg2Rad))
return true;
// 4. Find out whether the left line segment intersects with the disc
Vector2 q = l * new Vector2(Mathf.Cos(theta * Mathf.Deg2Rad), Mathf.Sin(theta * Mathf.Deg2Rad));
Vector2 p = new Vector2(px, py);
return SegmentPointSqrDistance(Vector2.zero, q, p) <= r * r;
}
边栏推荐
- unity3d:Assetbundle模拟加载,同步加载,异步加载,依赖包加载,自动标签,AB浏览器,增量打包
- Unity3D+moba+技能指示器(二)
- Unity3d:特效对象池,超时删除池内GameObject,GC权值
- C # custom stack
- 详解TCP的流量控制机制与拥塞控制机制
- Hcip --- condition matching and OSPF Protocol
- 学习日记——(路由与交换技术)ACL访问控制列表
- Knowledge points and skills of Wireshark network analysis is so simple
- Hcip --- mGRE comprehensive experiment
- GameFramework:资源热更代码分析,检查版本信息,下载版本文件,校验版本文件,得到更新文件数量,下载文件,TaskPool
猜你喜欢

InheritableThreadLocal与阿里的TransmittableThreadLocal设计思路解析

浅做一下思科实验吧!

超好用的抓包工具tcpdump

DHCP second experiment

HCIP---BGP相关配置
![[AUTOSAR storage stack NVM]](/img/7a/15e01f8ace647b55e11e764dba1b64.png)
[AUTOSAR storage stack NVM]

psutil监控的简单使用

Unity3d:ugui source code eventsystem input system FAQ

HCIP-第一次实验

Analysis of inheritablethreadlocal and Alibaba's transmittablethreadlocal design ideas
随机推荐
C#(CSharp) 微信公众号开发一 基本配置
Learning diary - (routing and switching technology) DHCP (Dynamic Host Configuration Protocol)
Analysis ideas of strong consistency and weak consistency and concurrency skills of distributed scenarios
@RequiredArgsConstructor注解使用
How to write a web page with a common text editor
如何解决if语句太多
读《凤凰架构》- RPC的历史与知识
在二叉排序树中删除节点
围棋能力概念与软件开发能力概念的对应
0动态规划 LeetCode1024. 视频拼接
OSPF的链路扩展配置
手动配置DHCP服务
C: stack stack source code, array stack, chain stack
Unity3d:ugui, UI and special effect particle level, bakemesh above 2018.2, particles between two images and in Scrollview
[database] basic theory
Unity3d: ugui source, Rebuild Optimization
Unity3d:ugui source code eventsystem input system FAQ
@Requiredargsconstructor annotation use
Unity3d:特效对象池,超时删除池内GameObject,GC权值
剖析Redis服务器