作为一个菜鸡,这个高中数学题差不多废了我两个上午。。。好了,废话不多说,直接上代码。。。

using System.Collections.Generic;
using UnityEngine; public class DrawAreaLine : MonoBehaviour
{
public bool IsAreaLineOn = false;
private LineRenderer AreaLine;
private List<Vector3> PosList = new List<Vector3>();
private RaycastHit hit;
private Ray ray;
private int num = ;
// Use this for initialization
void Start()
{
AreaLine = transform.Find("Area").GetComponent<LineRenderer>();
AreaLine.material = new Material(Shader.Find("Sprites/Default"));
AreaLine.startColor = Color.blue;
AreaLine.endColor = Color.blue;
AreaLine.startWidth = 0.05f;
AreaLine.endWidth = 0.05f;
AreaLine.numCornerVertices = ;
AreaLine.numCapVertices = ; } // Update is called once per frame
void Update()
{
BeginAreaLine();
} void BeginAreaLine()
{
if (IsAreaLineOn)
{
if (Input.GetMouseButtonDown())
{
if (AreaLine.enabled == false)
{
AreaLine.enabled = true;
}
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Vector3 pos = new Vector3(hit.point.x, hit.point.y, hit.point.z) + new Vector3(, 0.1f, );
//判断是否有相同位置的点
for (int i=; i<PosList.Count;i++)
{
if (PosList[i]==pos)
{
return;
}
}
if (AreaLine.positionCount >= )
{
return;
}
if (AreaLine.positionCount == )
{
//判断第四个点位置,判断能否组成四边形
//判断顺时针还是逆时针
if (IsClockWise() == false)//ABC为逆时针方向
{
//逆时针判断能否画四边形
if (IfCanAntiClock(pos) == false)
{
return;
}
}
if (IsClockWise() == true) //ABC为顺时针方向
{
//顺时针能否画四边形
if(IfCanClick(pos)==false)
{
return;
}
} }
if (hit.collider.name == "PanelCube")
{
num++;
AreaLine.positionCount = num;
AreaLine.SetPosition(num - , pos);
PosList.Add(pos);
if (PosList.Count == )
{
//计算三角形面积
// AreaTriabgle();
print(AreaTriabgle());
}
if (PosList.Count == )
{
//计算四边形面积
//AreaQuadrangle();
print(AreaQuadrangle());
}
}
//print(AreaLine.positionCount);
}
}
else if (Input.GetKeyDown(KeyCode.Delete))
{
DelectLine();
}
return;
}
} /// <summary>
/// 判断逆时针能不能画成四边形
/// </summary>
/// <param name="PosD"></param>
/// <returns>cyt</returns>
bool IfCanAntiClock(Vector3 PosD)
{
//直线一般式表达:(y2-y1)x-(x2-x1)y-x1y2+x2y1=0
bool can = false;
Vector2 A = new Vector2(PosList[].x, PosList[].z);
Vector2 B = new Vector2(PosList[].x, PosList[].z);
Vector2 C = new Vector2(PosList[].x, PosList[].z);
Vector2 D = new Vector2(PosD.x, PosD.z);
//D在直线AB、AC下方且在BC上方
if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y > )
&& (((C.y - A.y) * D.x - (C.x - A.x) * D.y - A.x * C.y + C.x * A.y > ))
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y < ))
{ can = false;
}
//D在AB上方且在BC、AC下方
else if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y < )
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y > )
&& (C.y - A.y) * D.x - (C.x - A.x) * D.y - A.x * C.y + C.x * A.y > )
{ can = false;
}
else
{
print("keyi");
can = true;
}
return can;
} /// <summary>
/// 顺时针能否画成四边形
/// </summary>
/// <param name="posD"></param>
/// <returns>cyt</returns>
bool IfCanClick(Vector3 PosD)
{
//直线一般式表达:(y2-y1)x-(x2-x1)y-x1y2+x2y1=0
bool CanClick = false;
Vector2 A = new Vector2(PosList[].x, PosList[].z);
Vector2 B = new Vector2(PosList[].x, PosList[].z);
Vector2 C = new Vector2(PosList[].x, PosList[].z);
Vector2 D = new Vector2(PosD.x, PosD.z);
//在AB、AC上方、BC下方,以ac为底边观察的
if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y < )
&& (((C.y - A.y) * D.x - (C.x - A.x) * D.y - A.x * C.y + C.x * A.y <))
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y >)
)
{
CanClick = false;
}
//在AC、BC上方,在AB下方
else if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y > )
&& (((C.y - A.y) * D.x - (C.x - A.x) * D.y - A.x * C.y + C.x * A.y < ))
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y < )
)
{
CanClick = false;
}
else
{
CanClick = true;
}
return CanClick;
}
/// <summary>
/// 计算三角形面积
/// </summary>
float AreaTriabgle()
{
//点到直线距离d=Mathf.Abs( (A*x0+B*y0+C)/Mathf.Sqrt(A*A+B*B) );
float area;
Vector2 A = new Vector2(PosList[].x, PosList[].z);
Vector2 B = new Vector2(PosList[].x, PosList[].z);
Vector2 C = new Vector2(PosList[].x, PosList[].z);
//AC长度(底边长)
float AC = Vector2.Distance(A, C);
//B到AC的距离(AC边的高)
float h = Mathf.Abs(((C.y - A.y) * B.x - (C.x - A.x) * B.y - A.x * C.y + C.x * A.y) / Mathf.Sqrt((C.y - A.y) * (C.y - A.y) + (C.x - A.x) * (C.x - A.x)));
area = AC * h / ;
return area;
}
/// <summary>
/// 计算四边形面积
/// </summary>
float AreaQuadrangle()
{
float area;
Vector2 A = new Vector2(PosList[].x, PosList[].z);
Vector2 B = new Vector2(PosList[].x, PosList[].z);
Vector2 C = new Vector2(PosList[].x, PosList[].z);
Vector2 D = new Vector2(PosList[].x, PosList[].z);
//AC长度(底边长)
float AC = Vector2.Distance(A, C);
//B到AC的距离(AC边的高)
float hB = Mathf.Abs(((C.y - A.y) * B.x - (C.x - A.x) * B.y - A.x * C.y + C.x * A.y) / Mathf.Sqrt((C.y - A.y) * (C.y - A.y) + (C.x - A.x) * (C.x - A.x)));
float hD = Mathf.Abs(((C.y - A.y) * D.x - (C.x - A.x) * D.y - A.x * C.y + C.x * A.y) / Mathf.Sqrt((C.y - A.y) * (C.y - A.y) + (C.x - A.x) * (C.x - A.x)));
//判断是否是凹四边形
if (IsConcaveQuadrilateral() == true)
{
area = AC * Mathf.Abs((hB - hD)) / ;
}
else
area = AC * (hB + hD) / ;
return area;
}
/// <summary>
/// 删除线
/// </summary>
void DelectLine()
{
num = ;
//lineRenderer.SetVertexCount(LengthOfLineRenderer);
AreaLine.positionCount = num;
PosList.Clear();
AreaLine.enabled = false;
} /// <summary>
/// 判断是否是凹四边形
/// </summary>
/// <returns>cyt</returns>
bool IsConcaveQuadrilateral()
{
bool Concave = false;
Vector2 A = new Vector2(PosList[].x, PosList[].z);
Vector2 B = new Vector2(PosList[].x, PosList[].z);
Vector2 C = new Vector2(PosList[].x, PosList[].z);
Vector2 D = new Vector2(PosList[].x, PosList[].z);
//逆时针状况
//两种情况,一种是D在三角形ABC内部,另一种是D在直线AB跟BC下方(以ab为底边观察)
if (IsClockWise()==false)
{
if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y < )
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y < )
&& ((C.y - A.y) * D.x - (C.x - A.x) * D.y - A.x * C.y + C.x * A.y > ))
{
Concave = true;
}
else if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y > )
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y > ))
{
Concave = true;
}
else
{
Concave = false;
}
}
//顺时针
//两种情况,在三角形abc内部和在AB上、AC下
if (IsClockWise()==true)
{
if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y > )
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y > )
&& ((C.y - A.y) * D.x - (C.x - A.x) * D.y - A.x * C.y + C.x * A.y < )
)
{
Concave = true;
}
else if (((B.y - A.y) * D.x - (B.x - A.x) * D.y - A.x * B.y + B.x * A.y < )
&& ((C.y - B.y) * D.x - (C.x - B.x) * D.y - B.x * C.y + C.x * B.y <
))
{
Concave = true;
}
else
{
Concave = false;
}
}
return Concave;
}
/// <summary>
/// 判断是否为顺时针,以ac为底边观察
/// </summary>
/// <param>cyt</param>
/// <returns></returns>
bool IsClockWise()
{
bool IsClock = false;
Vector2 A = new Vector2(PosList[].x, PosList[].z);
Vector2 B = new Vector2(PosList[].x, PosList[].z);
Vector2 C = new Vector2(PosList[].x, PosList[].z);
//如果B在A的右边,C在AB上方为逆时针
if (B.x>=A.x)
{
if ((B.y - A.y) * C.x - (B.x - A.x) * C.y - A.x * B.y + B.x * A.y < )
{
IsClock = false;
}
else
{
IsClock = true;
}
}
//如果B在A的左边,C在AB下方为逆时针
if (B.x<A.x)
{
if ((B.y - A.y) * C.x - (B.x - A.x) * C.y - A.x * B.y + B.x * A.y < )
{
IsClock = false;
}
else
{
IsClock = true;
}
}
return IsClock;
}
}

注释还算比较清楚,各种情况都判断了,也是想过用向量来判断能否实现,发现不好使....

  AreaLine = transform.Find("Area").GetComponent<LineRenderer>();这个跟
     if (hit.collider.name == "PanelCube")这两句需要自己在场景中设置一下,然后运行的时候把脚本的
IsAreaLineOn变量设为true就能画了...按下delect可以删除画的四边形,然后在点击就可以继续画了。
实现思路的话首先将所有的点加入一个集合中(每次输入都排除了重复的点),然后根据集合里的的前三个点判断画的三角形是顺时针画的三角形还是逆时针画的三角形,
然后在根据是顺时针和逆时针分别判断第四个点的位置,判断第四个点在三角形三条边所在直线的位置判断能否画成四边形。
计算面积的话是先判断了顺时针话还是逆时针画,然后分别判断画的是凸四边形还是凹四边形,然后在计算面积。
哎。。。生无可恋。。。。
希望能帮到人,若需转载请标明出处,谢谢....

unity 用LineRender画四边形并测面积的更多相关文章

  1. Delphi下OpenGL2d绘图(04)-画四边形

    一.前言 画四边形基本上与前几遍文字代码是相同.区别在于glBegin()的参数“GL_QUADS”.绘制的框架代码可以使用 Delphi下OpenGL2d绘图(01)-初始化 中的代码.修改的部份为 ...

  2. 百度地图API画多边型,测面积

    效果: 脚本: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  3. Unity之屏幕画线

    using UnityEngine;using System.Collections; public class DrawRectangle : MonoBehaviour { public Colo ...

  4. Unity中用Mesh画一个圆环

    Probuider 前几天在做一个小项目的时候,用到了Unity自带的一个包ProBuilder其中的Arch生成1/4圆. 挺好玩的,可以在直接Unity中根据需要用Mesh定制生成图形,而不用建模 ...

  5. html5画四边形

    <canvas id='test02'></canvas> <script> var canvas = document.getElementById('test0 ...

  6. Unity使用GL画线

    脚本需挂在相机上,如果你的脚本,编辑器报错了,Matrix stack full depth reached,加上这个方法试试GL.LoadPixelMatrix(); using System.Co ...

  7. Unity中用Mesh画一个圆环(二)

    中目标-生成完整面 在之前的内容中我们已经成功生成了一个面,接下来我们要生成剩下的面就很容易了. 我们把之前生成的面当作顶面,接着我们来生成底面. 还记得前面说过\(\color{#1E90FF}{D ...

  8. ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测

    一.开篇 在博客注册了三年,今天才决定写第一篇博客,警告自己不要懒!!! 二.关于ArcGIS JS 版本选择 在写这篇博客时ArcGIS JS 4.0正式版已经发布.它和3.x版本的不同是,Map不 ...

  9. ArcGIS Engine开发之量测功能

    1.距离测量 距离测量时,片段长度通过两点之间距离计算得到,全部长度通过片段长度的和计算得到.主要用到INewLineFeedback和IScreenDisplay两个接口. 1)INewLineFe ...

随机推荐

  1. mybatis查询mysql的datetime类型数据时间差了14小时

    场景: 数据库字段: mybatis使用 now() 生成时间. 结果: 使用mybatis查询mysql中的数据时,所有时间都比数据库时间多了14小时,考虑了一下,初步判定是系统时区的问题.因为my ...

  2. Spring源码解析之PropertyPlaceholderHelper(占位符解析器)

    Spring源码解析之PropertyPlaceholderHelper(占位符解析器) https://blog.csdn.net/weixin_39471249/article/details/7 ...

  3. ES6 - 数组扩展(扩展运算符)

    扩展运算符 扩展运算符(spread)是三个点(...).它好比 rest 参数的逆运算(函数),将一个数组转为用逗号分隔的参数序列. rest: 变量将多余的参数放入数组中. spread(扩展): ...

  4. [转]manjaro安装vmware虚拟机

    全球领先的信息与通信解决方案供应商华为,近日面向全球ICT从业者,以及有兴趣掌握ICT相关知识的人士,免费推出其图形化网络仿真工具平台—eNSP.该平台通过对真实的网络设备的仿真模拟,帮助广大ICT从 ...

  5. IfcRoot

    IfcRoot is the most abstract and root class for all entity definitions that roots in the kernel or i ...

  6. 内存自动清理.sql

    --清除存储过程缓存 DBCC FREEPROCCACHE --注:方便记住关键字 FREEPROCCACHE可以拆解成 FREE(割舍,清除) PROC(存储过程关键字简写),CACHE(缓存) - ...

  7. 多用户同时操作一条Mysql记录问题

    场景:两个用户同时读取了数据库中的一条记录,此时用户A对其中一个字段的值进行了修改操作并进行了提交,后来用户B也对这个字段进行了修改,用户B的提交将会覆盖用户A提交的值 关于乐观锁和悲观锁 悲观锁:每 ...

  8. kafka 如何保证数据不丢失

    一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数据不丢失,在面试中也会问到相关的问题.但凡遇到这种问题,是指3个方面的数据不丢失,即:producer consumer 端数据不丢失  b ...

  9. Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制

    思路: 动态路由实现:在导航守卫中判断用户是否有用户信息,通过调用接口,拿到后台根据用户角色生成的菜单树,格式化菜单树结构信息并递归生成层级路由表并使用Vuex保存,通过 router.addRout ...

  10. Ramdisk根文件系统映像的修改与创建

    本文简述Ramdisk根文件系统映像的修改以及创建,并附相关脚本以实现自动化配置,而根文件系统的制作过程请网上自行搜索.相关过程尽可能以图的方式展示出来,重在说明操作的过程,仅供参考. Ramdisk ...