目标:
时间:
产出:
1、计算四边形区域的中心点
/// <summary>
/// 获取不规则多边形几何中心点
/// </summary>
/// <param name="mPoints"></param>
/// <returns></returns>
public Vector2 GetCenterPoint(List<Vector2> mPoints)
{
float cx = (GetMinX(mPoints) + GetMaxX(mPoints)) / 2;
float cy = (GetMinY(mPoints) + GetMaxY(mPoints)) / 2;
return new Vector2(cx, cy);
}
/// <summary>
/// 获取最小X值
/// </summary>
/// <param name="mPoints"></param>
/// <returns></returns>
private float GetMinX(List<Vector2> mPoints)
{
float minX = 0;
if (mPoints.Count > 0)
{
minX = mPoints[0].x;
foreach (Vector2 point in mPoints)
{
if (point.x < minX)
minX = point.x;
}
}
return minX;
}
/// <summary>
/// 获取最大X值
/// </summary>
/// <param name="mPoints"></param>
/// <returns></returns>
private float GetMaxX(List<Vector2> mPoints)
{
float maxX = 0;
if (mPoints.Count > 0)
{
maxX = mPoints[0].x;
foreach (Vector2 point in mPoints)
{
if (point.x > maxX)
maxX = point.x;
}
}
return maxX;
}
/// <summary>
/// 获取最小Y值
/// </summary>
/// <param name="mPoints"></param>
/// <returns></returns>
private float GetMinY(List<Vector2> mPoints)
{
float minY = 0;
if (mPoints.Count > 0)
{
minY = mPoints[0].y;
foreach (Vector2 point in mPoints)
{
if (point.y < minY)
minY = point.y;
}
}
return minY;
}
/// <summary>
/// 获取最大Y值
/// </summary>
/// <param name="mPoints"></param>
/// <returns></returns>
private float GetMaxY(List<Vector2> mPoints)
{
float maxY = 0;
if (mPoints.Count > 0)
{
maxY = mPoints[0].y;
foreach (Vector2 point in mPoints)
{
if (point.y > maxY)
maxY = point.y;
}
}
return maxY;
}
/// <summary>
/// 获取不规则多边形重心
/// </summary>
/// <param name="mPoints"></param>
/// <returns></returns>
public Vector2 GetCenterOfGravityPoint(List<Vector2> mPoints)
{
float area = 0.0f; //多边形面积
float gx = 0.0f, gy = 0.0f; // 重心的x、y
for (int i = 1; i <= mPoints.Count; i++)
{
float iX = mPoints[i % mPoints.Count].x;
float iY = mPoints[i % mPoints.Count].y;
float nextX = mPoints[i - 1].x;
float nextY = mPoints[i - 1].y;
float temp = (iX * nextY - iY * nextX) / 2.0f;
area += temp;
gx += temp * (iX + nextX) / 3.0f;
gy += temp * (iY + nextY) / 3.0f;
}
gx = gx / area;
gy = gy / area;
Vector2 v2 = new Vector2(gx, gy);
return v2;
}
2、判断点是否在区域内
/// <summary>
/// 判断点是否在区域内
/// </summary>
/// <param name="polyPoints"></param>
/// <param name="p"></param>
/// <returns></returns>
public bool ContainsPoint(List<Vector2> polyPoints, Vector2 p)
{
var j = polyPoints.Count - 1;
var inside = false;
for (int i = 0; i < polyPoints.Count; j = i++)
{
var pi = polyPoints[i];
var pj = polyPoints[j];
if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) &&
(p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x))
inside = !inside;
}
return inside;
}
3、区域内随机生成多个点
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
public class ModelControlManager : MonoBehaviour
{
public Transform trans;
public List<Transform> lisTrans = new List<Transform>();
public List<Vector2> listV2 = new List<Vector2>();
public bool isRandom = false;
public bool isRandomPoint = false;
private float minX, maxX, minY, maxY;
public List<Vector2> listRandomPoints = new List<Vector2>();
public Transform trans1;
public Transform trans2;
void Start()
{
foreach (var item in lisTrans)
{
Vector2 v2 = new Vector2(item.position.x, item.position.z);
if(!listV2.Contains(v2))
listV2.Add(v2);
}
minX = Mathf.Min(listV2[0].x, listV2[1].x, listV2[2].x, listV2[3].x);
maxX = Mathf.Max(listV2[0].x, listV2[1].x, listV2[2].x, listV2[3].x);
minY = Mathf.Min(listV2[0].y, listV2[1].y, listV2[2].y, listV2[3].y);
maxY = Mathf.Max(listV2[0].y, listV2[1].y, listV2[2].y, listV2[3].y);
}
private void Update()
{
if (isRandom)
{
isRandom = false;
isRandomPoint = true;
listRandomPoints.Clear();
}
if (isRandomPoint)
{
float x = Random.Range(minX, maxX);
float y = Random.Range(minY, maxY);
Vector2 v2 = new Vector2(x, y);
bool isArea = ContainsPoint(listV2, v2);
if (isArea)
{
if (!listRandomPoints.Contains(v2))
listRandomPoints.Add(v2);
if (listRandomPoints.Count>=2)
{
isRandomPoint = false;
trans1.position = new Vector3(listRandomPoints[0].x,trans1.position.y,listRandomPoints[0].y);
trans2.position = new Vector3(listRandomPoints[1].x,trans2.position.y,listRandomPoints[1].y);
}
}
}
}
public bool ContainsPoint(List<Vector2> polyPoints, Vector2 p)
{
var j = polyPoints.Count - 1;
var inside = false;
for (int i = 0; i < polyPoints.Count; j = i++)
{
var pi = polyPoints[i];
var pj = polyPoints[j];
if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) &&
(p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x))
inside = !inside;
}
return inside;
}
}