本文思路:在凸多边形的基础上将凹多边形用向量延长线法分割成多个凸多边形,然后按照凸多边形的算法计算。凸多边形比较简单,就不介绍记录了。

几个凹多边形算法的思路:

http://blog.csdn.net/sun_shine_/article/details/18799739   //任意多边形面积计算
http://www.cnblogs.com/wantnon/p/6384771.html   //直线切割凹多边形(不带洞?)
http://blog.csdn.net/heyuchang666/article/details/51382757   //向量法和旋转法切割凹多边形

限制:
1.顶点数组必须是有序(顺时针或者逆时针)。
2.不支持带洞的。
3.需要将Z轴值置0.
思路流程:
1.顶点有序化。(此文暂时不记录)
2.顶点数组转换成对应的方向向量数组。
3.依次利用叉乘查找到第一个凹多边形的凹点。
4.从这个点开始往后找到这个凹点的向量延长先在之后的向量上的第一个交点。(注意顺序,而不是从数组0开始)
5.以这个交点为界限把凹多边形分为两个多边形。
6.递归这个切分算法,直至不再有凹多边形出现为止。
7.得到的多个多边形都是属于凸多边形,利用凸多边形算法计算。
static TArray<TArray<FVector>> t_polygonDividedArr;
/*从多边形的有序的点数组获取顶点和三角面数据信息(凹凸多边形)参数1: 顶点数组参数2: 是否是逆时针*/
static void GetPolygonDataFromOrderVertexs(TArray<FVector> _points,bool _antiClockwise=true);
void ULcq_BlueprintFunctionLibrary::GetPolygonDataFromOrderVertexs(TArray<FVector> _points, bool _antiClockwise)
{TArray<FLcq_PolygonData> t_res;int t_pointsNum = _points.Num();if (t_pointsNum>3){t_polygonDividedArr.Empty();DividePolygonIfConcave(_points, _antiClockwise);  //递归if (t_polygonDividedArr.Num()>0){UE_LOG(LogTemp, Warning, TEXT("多边形分割成了%d  个多边形"), t_res.Num());}}elseUE_LOG(LogTemp, Error, TEXT("多边形分割失败"));
}//分割
/*检查多边形是否是凹多边形,如果是就切割参数1:点集参数2:需要返回的被切割多边形1参数2:需要返回的被切割多边形2*/
static void DividePolygonIfConcave(TArray<FVector> _points, bool _antiClockwise = true);
void ULcq_BlueprintFunctionLibrary::DividePolygonIfConcave(TArray<FVector> _points, bool _antiClockwise)
{int t_pointsNum = _points.Num();  if (_points.Num()<3){return;}if (t_pointsNum==3){t_polygonDividedArr.Add(_points);return;} if (t_pointsNum>3){TArray<FVector> _dividePolygonA;TArray<FVector> _dividePolygonB;float t_hei = _points[0].Z;  SetPointsZvalueBySpecify(_points,0);FVector t_p1;FVector t_p2;  TArray<FVector> t_dirs=GetVectorArrByPointsArr(_points);bool t_divideResult=false;int t_indexNew=0;for (int i=0;i<t_dirs.Num();i++){         t_p1 = t_dirs[i];if (i == t_dirs.Num()-1){t_p2 = t_dirs[0];t_indexNew = 0;}else{t_p2 = t_dirs[i + 1];t_indexNew = i + 1;}float t_rotateDir = FVector::CrossProduct(t_p1, t_p2).Z;         //检查出是凹多边形if (t_rotateDir<-0.01f&&_antiClockwise == true || t_rotateDir>0.01f&& _antiClockwise == false){//UE_LOG(LogTemp, Warning, TEXT("t_rotateDir:   %f"), t_rotateDir);UE_LOG(LogTemp, Warning, TEXT("是凹多边形~~~~~~~~~~~"));//求分割点t_divideResult = GetRayIntersectionOfVecInVecArr(t_dirs, _points, i, i, t_pointsNum - 1, _dividePolygonA, _dividePolygonB);if (t_divideResult == false){t_divideResult = GetRayIntersectionOfVecInVecArr(t_dirs, _points, i, 0, i - 1, _dividePolygonA, _dividePolygonB);}if (t_divideResult == false){UE_LOG(LogTemp, Error, TEXT("线段%d  没有得到分割点"), i);}break;}             }if (t_divideResult ==false){ SetPointsZvalueBySpecify(_points, t_hei);t_polygonDividedArr.Add(_points);}else{if (_dividePolygonA.Num()>2){SetPointsZvalueBySpecify(_dividePolygonA, t_hei);DividePolygonIfConcave(_dividePolygonA, _antiClockwise);}if (_dividePolygonB.Num()>2){SetPointsZvalueBySpecify(_dividePolygonB, t_hei);DividePolygonIfConcave(_dividePolygonB, _antiClockwise);}}}
}/*给定点数组的Z值统一化*/
static bool SetPointsZvalueBySpecify(TArray<FVector> &_points, float _zValue);
bool ULcq_BlueprintFunctionLibrary::SetPointsZvalueBySpecify(TArray<FVector> &_points, float _zValue)
{if (_points.Num()>0){for (int i=0;i<_points.Num();i++){_points[i].Z = _zValue;}return true;}return false;
}/*根据点数组获取向量数组*/
static TArray<FVector> GetVectorArrByPointsArr(const TArray<FVector> _points);
TArray<FVector> ULcq_BlueprintFunctionLibrary::GetVectorArrByPointsArr(const TArray<FVector> _points)
{TArray<FVector> t_res;int t_pointsNum = _points.Num();if (t_pointsNum>1){FVector t_p1;FVector t_p2;for (int i = 0; i < _points.Num(); i++){t_p1 = _points[i];if (i == t_pointsNum - 1){t_p2 = _points[0];}else{t_p2 = _points[i + 1];}       t_res.Add(t_p2 - t_p1);}}return t_res;
}/*从向量数组中获取一个向量在这个数组中的延长线与其他向量的交点注意:顺序必须先从这个向量的下标开始,不能是0;交点不包括向量端点参数1:方向向量数组参数2:对应的点数组(长度需保持一致)参数3:这个向量的下标参数4,5:开始和结束下标参数6,7: 根据交点被切分的两组点数组返回值:true 为成功,反之无*/static bool GetRayIntersectionOfVecInVecArr(const TArray<FVector> _dirs, const TArray<FVector> _points, const int _vecIndex, const int _beginIndex, const int _endIndex,TArray<FVector> &_dividePolygonA, TArray<FVector> &_dividePolygonB);
bool ULcq_BlueprintFunctionLibrary::GetRayIntersectionOfVecInVecArr(const TArray<FVector> _dirs, const TArray<FVector> _points, const int _vecIndex,const int _beginIndex,const int _endIndex,TArray<FVector> &_dividePolygonA,TArray<FVector> &_dividePolygonB)
{int t_dirsNum=_dirs.Num();int t_pointsNum = _points.Num();if (t_dirsNum>3&&t_pointsNum>3){if (t_dirsNum==t_pointsNum){if (_beginIndex>=0&&_beginIndex<t_dirsNum){if (_endIndex>=0&&_endIndex<t_dirsNum){int t_indexNew = _vecIndex == (t_dirsNum - 1) ? 0 : _vecIndex + 1;FVector t_beginA = _points[_vecIndex];FVector t_endA = t_beginA + _dirs[_vecIndex];FVector t_intersectionPoint;for (int j = _beginIndex; j <= _endIndex; j++){if (j != _vecIndex&&j != t_indexNew){FVector t_beginB = _points[j];if (CheckTwoLineIntersectionResult(t_beginA, t_endA, t_beginB, t_beginB + _dirs[j], t_intersectionPoint) == 2){//给分割的多边形点组加点_dividePolygonA = GetPointsByIndexRange(_points, t_indexNew, j);_dividePolygonA.Add(t_intersectionPoint);UE_LOG(LogTemp, Warning, TEXT("_dividePolygonA向量数组个数: %d"), _dividePolygonA.Num());_dividePolygonB = GetPointsByIndexRange(_points, j, t_indexNew);if (_dividePolygonB.Num() > 0){_dividePolygonB[0] = t_intersectionPoint;}UE_LOG(LogTemp, Warning, TEXT("_dividePolygonB向量数组个数: %d"), _dividePolygonB.Num());return true;}}}}}           }}return false;
}

UE4 凹多边形渲染相关推荐

  1. ue4cmd怎么调用_[UE4,automation]UE4批渲染cmd篇

    之前做项目的过程中,有一部分工作是在UE4里制作输出小短片.由于要完成的量比较大,所以研究了一些批渲染的方法. 逻辑上跟以前在maya里用batch render差不多,不过UE4这边的设置相对繁琐一 ...

  2. Nicholas谈UE4高级渲染:动态光照迭代快

    GameLook报道/6月5日,2015年第三期GameLook开放日‧虚幻引擎专场活动在上海正式举行,此次活动由Epic Games与GameLook联合主办. 如何用好UE4引擎,发挥其强大的画面 ...

  3. ue4 android 贴图,【腾讯GAD】做一张用于UE4实时渲染的写实级别面部贴图

    原标题:[腾讯GAD]做一张用于UE4实时渲染的写实级别面部贴图 我的名字是Braulio "Brav"FG.我来自哥斯达黎加的圣何塞.接下来我将讲解如何在UE4中使用Textur ...

  4. UE4文本渲染器Text Render技巧与支持中文

    UE4文本渲染器Text Render技巧与支持中文 首先来支持中文 在目录中新建Font 修改类型 选择天下第一的思源字体 字号根据字体,选择生成以后能看清的最小 大小 字号太小会模糊,太大占资源 ...

  5. UE4透明渲染层级错误问题

    UE4透明渲染层级错误问题 原因 尝试 解决 两个透明物体,当摄像机处于不同位置时,可能会出现渲染层次错误问题.如下图: 在路径的前半段和后半段都是正确的 中间段出现线条渲染在标签前面情况 原因 可能 ...

  6. ue4云渲染——像素流送实践

    一.安装 Epic Games Launcher 官方中文文档 https://docs.unrealengine.com/4.27/zh-CN/,点击下载 如需要登录账号,使用注册一个账号后再登录就 ...

  7. ue4 离线渲染_[译]Real Shading in Unreal Engine 4(UE4中的真实渲染)(2)

    利用假期接着把剩下的部分搞完吧,其实,纯粹的翻译应该还是比较简单的,但是,为了更好地理解,我一般都会多找一些资料来进行互相印证.在上面一部分Shader Model的改变过程中,我主要是参考了一些PB ...

  8. UE4实时渲染基础及深入探究

    实时渲染基础:link 实时渲染深入探究:link 目录 实时渲染基础 目标帧率与毫秒 帧时间与GPU/CPU 最常见的四大性能问题 实时渲染深入探究 延迟渲染与前向渲染 渲染之前和遮挡 CPU和GP ...

  9. ue4 离线渲染_UE4基础:离线安装方法(附UE4.25.0离线安装包下载)

    注意:离线安装是指不用通过Epic的客户端下载巨大的安装包,但是某些步骤还是需要网络连接的.并且Epic的账号也是需要的. 下载地址见文章最下方 为什么要离线安装? 离线安装并不是必须的,老王亲测从官 ...

最新文章

  1. 通用流水线处理器技术参数
  2. LintCode: Binary Tree Inorder Traversal
  3. HDOJ 3966 Aragorn#39;s Story
  4. 解决:无法解析的外部符号__iob_func
  5. 过滤日志中不相关的堆栈跟踪行
  6. elementUI-添加自定义图标
  7. php 分割二维数组,拆分二维数组 php
  8. 你的密码安全吗?——索尼事件的教训
  9. mysql实现主从复制
  10. 格力:核心科技有时也是高利贷
  11. influxDB框架 数据存储 TSM 数据操作等详解
  12. 频谱感知2:衰落信道上未知信号的能量检测
  13. 最常用20000英语单词表_受够加班煎熬,我整理出10条职场人士最常用的透视表技巧!(下篇)...
  14. 新型城镇化提质扩容 打造民村智慧城市
  15. html如何给图片加链接
  16. JDK-8274609 JEP 421: Deprecate Finalization for Removal
  17. RTKLIB专题学习(七)---精密单点定位实现初识(三)
  18. 短线盈亏指标 股票市场盈亏指标cys 盈亏指标分析选股公式副图
  19. 蓄力-利用POI进行excel的导入导出(包含图片)
  20. [iOS]转让APP

热门文章

  1. Java-数据结构:树,这份资料可帮你解决95%的问题
  2. Hbuilder 真机运行显示未受信任的解决方法(ios)
  3. 重磅!《深度学习 500 问》已更新,(附完整下载)
  4. 理解线性变换和基(坐标)变换
  5. 金蝶记账王、迷你版、标准版引入凭证方法
  6. 总结Python中的字符串格式化
  7. 【bzoj1905】捉迷藏(线段树)
  8. 分享时的缩略图不显示问题
  9. 纯java编写的联机五子棋项目(附带开源链接)
  10. 【算法刷题日记之本手篇】井字棋与密码强度等级