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

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. somatic mutation体细胞变异检测文献分享--转载

    转载 :http://blog.sina.com.cn/s/blog_83f77c940102xuro.html Kalatskaya I, Trinh Q M, Spears M, et al. I ...

  2. Thinkphp5 实现动态模板主题多个模板切换

    在项目开发过程中会遇到一个网站有不同风格,本文详细介绍Thinkphp5 实现模板主题多个模板切换 一.在Config中配置view_path模板路径代码如下 1 2 3 4 5 6 7 8 9 10 ...

  3. but only one is allowed(重复处理跨域请求)

    情景:vue的项目中在本地调试项目,在前端的跨域配置没有问题的情况下,出现这样的报错. 解决方案,参考: https://www.cnblogs.com/zsg88/articles/11576324 ...

  4. JKS转PFX

    通过jks2pfx工具 请下载:JKS2PFX转换工具. 将压缩包解开到 c:\jks2pfx 目录下, 运行以下命令:JKS2PFX <导出文件名> [Java Runtime的目录]备 ...

  5. [转]10 Best GTK Themes for Ubuntu 18.04

    原文地址:https://omgfoss.com/10-best-gtk-themes-ubuntu-18-04/

  6. C# HashSet集合类型使用介绍

    1.HashSet集合 使用HashSet可以提高集合的运算.使用HashSet集合不自带排序方法,如果需要排序的需求可以参考使用List<T>集合配合Sort方法. HashSet的优势 ...

  7. mvn-dependencies-vs-dependencyManagement

    dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显式的声明需要用的依赖. dependencies 相对于dependencyManagement,所有声明在dep ...

  8. Jmeter(一) Jmeter基本使用

    1.下载安装 官方网站 https://jmeter.apache.org/download_jmeter.cgi 选择下载即可 2.基本使用 下载解压后,目录如下: 进入到bin目录, 双击jmet ...

  9. Vue父子组件相互传值及调用方法的方案

    Vue父子组件相互传值及调用方法的方案 一.调用方法: 1.父组件调用子组件方法: 2.子组件调用父组件方法: 参考:https://www.cnblogs.com/jin-zhe/p/9523782 ...

  10. SpringBoot应用部署到Docker上(docker-io版本)

    配置TCP远程连接 为什么要配置这个呢,因为用到的docker-maven-plugin插件默认连接到localhost:2375上的docker.然而:1. 我们的Docker不在本地,执行打包命令 ...