#include "stdafx.h"
#include "OpenGL.h"
#include "Map.h"
#include "math.h"
#include "ArrayInterTriangle.h"
#include <iostream.h>
#include <stdio.h>
#include <bitset>
extern unsigned int m_ID;
#include <math.h>
#include<stdexcept>
#include<time.h>
extern bool Lbutdown; // 鼠标左键
extern bool Rbutdown; // 鼠标左键
//
extern HWND hWnd;
//定义最近的距离视点最近的鼠标物体:
//定义一个结构来保存所有的物体:
#include<list>
int TreeDepth=0;
#include<vector>
using std::bitset;
using std::list;
using std::vector;
using std::runtime_error;
using std::length_error;
vector<int> TheDividerList;
class Triangle{
public:
float a[3];
float b[3];
float c[3];
};
class TheTreeObect{
int maxlen;
int n;
//定义当前分割平面的索引。
int currentFlip;
Triangle *Triangles;
public:
void SetAsNode(int currentFlip){
Triangle temp=Triangles[currentFlip];
delete [] Triangles;
Triangles=new Triangle(temp);
}
void deleteALL(){
delete[] Triangles;
Triangles=NULL;
n=0;
}
void resetTriangle(Triangle *Triangles,int n){
delete[] this->Triangles;
this->Triangles=Triangles;
this->n=n;
this->maxlen=n;
}
TheTreeObect(){
Triangles= new Triangle[10];
maxlen=10;
n=0;
}
int add(Triangle triangle)
{
if(n==maxlen){
Triangle* temp=Triangles;
Triangles=new Triangle[n+10];
for(int i=0;i<n;i++){
for(int j=0;j<3;j++){
Triangles[i].a[j]=temp[i].a[j];
Triangles[i].b[j]=temp[i].b[j];
Triangles[i].c[j]=temp[i].c[j];
}
}
delete [] temp;
}
for(int j=0;j<3;j++){
Triangles[n].a[j]=triangle.a[j];
Triangles[n].b[j]=triangle.b[j];
Triangles[n].c[j]=triangle.c[j];
}
n++;
return n;
}
int getFlip(){
return currentFlip;
}
int getN(){
return n;
}
Triangle *getTriangles()
{
return Triangles;
}
TheTreeObect(float (*triangle)[3][3],int n1)
{
Triangles= new Triangle[n1];
n=n1;
for(int i=0;i<n;i++){
for(int j=0;j<3;j++){
//第二维表示点的索引,第三维表示,xyz坐标
Triangles[i].a[j]=triangle[i][0][j];
Triangles[i].b[j]=triangle[i][1][j];
Triangles[i].c[j]=triangle[i][2][j];
}
}
}
};
//而叉树节点是一个特殊的物体。。它只有一个平面。
class BSPNode:public TheTreeObect{
public:
BSPNode(){
IsLeaf=true;
}
//是否为分割面。或是是物体,或者是分割面。
bool IsLeaf;
bool IsWithObject;
void setIsWithObject(bool is)
{
IsWithObject=is;
}
BSPNode(TheTreeObect& obj):TheTreeObect(obj){
}
void set(bool Front)
{
IsFront=Front;
}
bool IsNode;
bool IsFront;
TheTreeObect* pBackChild;
TheTreeObect* pFrontChild;
//查看物体的第index个三角形是否与既定面共面。
void outPutSanjiao(Triangle triangle)
{
float *a=triangle.a;
float a0=a[0];
float a1=a[1];
float a2=a[2];
cout<<endl<<a0<<" "<<a1<<" "<<a2<<" "<<endl;
float *b=triangle.b;
float b0=b[0];
float b1=b[1];
float b2=b[2];
cout<<b0<<" "<<b1<<" "<<b2<<" "<<endl;
float *c=triangle.c;
float c0=c[0];
float c1=c[1];
float c2=c[2];
cout<<c0<<" "<<c1<<" "<<c2<<" "<<endl;
}
void outPutSanJiaos(Triangle* pTriangle,int n)
{
for(int i=0;i<n;i++)
{
outPutSanjiao(pTriangle[i]);
}
}
void outPutVector(char *p,float *pf,int n)
{
for(int j=0;p[j]!='\0';p++)
{
cout<<p[j];
}
cout<<":"<<endl;
for(int i=0;i<n;i++)
{
cout<<pf[i]<<endl;
}
}
//函数功能:判断一个三角形来自另外一个三角形所在平面的何方。
//功能描述:如果共面,则same为true,divided为false,方向相同则返回true,否则返回false;
// 如果不共面,则根据在前还是后,还是divided ,进行返回。
bool IsFomFront(TheTreeObect obj,int index,int currentFlip,bool &same,bool &divied){
divied=false;
same=false;
bitset<3> position[3];
float dir[3];
bool Front[3];
bool IsNotInFlat[3];
float point[3];
memcpy(point,obj.getTriangles()[index].a,3*sizeof(float));
//int currentFlip=getFlip();
VectBinus(obj.getTriangles()[currentFlip].a,point,dir);
outPutVector("射线原点",point,3);
outPutVector("射线终点",obj.getTriangles()[currentFlip].a,3);
outPutVector("射线方向",dir,3);
IsNotInFlat[0]=IsIntersectWithTriangle(
point,
dir,
obj.getTriangles()[currentFlip].a,
obj.getTriangles()[currentFlip].b,
obj.getTriangles()[currentFlip].c,
point,
Front[0]
);
cout<<"********************开始射线检测****************************************"<<endl;
cout<<"分割面为"<<endl;
outPutSanjiao(obj.getTriangles()[currentFlip]);
if(!IsNotInFlat[0])cout<<"射线在平面上"<<endl;
else if(Front[0])cout<<"射线从前方穿过"<<endl;
else cout<<"射线从后方穿过"<<endl;
cout<<"********************检测结束****************************************"<<endl;
memcpy(point,obj.getTriangles()[index].b,3*sizeof(float));
VectBinus(obj.getTriangles()[currentFlip].b,point,dir);
IsNotInFlat[1]=IsIntersectWithTriangle(
point,
dir,
obj.getTriangles()[currentFlip].a,
obj.getTriangles()[currentFlip].b,
obj.getTriangles()[currentFlip].c,
point,
Front[1]
);
cout<<"********************开始射线检测****************************************"<<endl;
outPutVector("射线原点",point,3);
outPutVector("射线方向",dir,3);
cout<<"分割面为"<<endl;
outPutSanjiao(obj.getTriangles()[currentFlip]);
if(!IsNotInFlat[1])cout<<"射线在平面上"<<endl;
else if(Front[1])cout<<"射线从前方穿过"<<endl;
else cout<<"射线从后方穿过"<<endl;
cout<<"********************检测结束****************************************"<<endl;
memcpy(point,obj.getTriangles()[index].c,3*sizeof(float));
VectBinus(obj.getTriangles()[currentFlip].c,point,dir);
IsNotInFlat[2]=IsIntersectWithTriangle(
point,
dir,
obj.getTriangles()[currentFlip].a,
obj.getTriangles()[currentFlip].b,
obj.getTriangles()[currentFlip].c,
point,
Front[2]
);
cout<<"********************开始射线检测****************************************"<<endl;
outPutVector("射线原点",point,3);
outPutVector("射线方向",dir,3);
cout<<"分割面为"<<endl;
outPutSanjiao(obj.getTriangles()[currentFlip]);
if(!IsNotInFlat[2])cout<<"射线在平面上"<<endl;
else if(Front[2])cout<<"射线从前方穿过"<<endl;
else cout<<"射线从后方穿过"<<endl;
cout<<"********************检测结束****************************************"<<endl;
for(int i=0;i<3;i++)
{
if(!IsNotInFlat[i])position[i].set(0);else
if(Front[i])position[i].set(1);else
position[i].set(2);
}
for(i=0;i<3;i++)
{
cout<<"i:顶点"<<i<<endl;
cout<<position[i][0];
cout<<position[i][1];
cout<<position[i][2];
}
//每个点的三个状态对应为 position[0],position[1],position[2];
bitset<3> positi=position[0]&position[1]&position[2];
for(i=0;i<3;i++)
{
cout<<"综合:";
cout<<positi[i]<<endl;
}
//查看是否共面
//分析结果为:
cout<<"经过分析,三角形与平面的关系为:"<<endl;
if(positi[0])
{ cout<<"这是一个相同的平面"<<endl;
same=true;
//查看方向是否相同
//求得他们的发线:
float flat_3_flip[3];
float flat_3_temp[3];
qiuFaXiangLiang(
getTriangles()[currentFlip].a,
getTriangles()[currentFlip].b,
getTriangles()[currentFlip].c,
flat_3_flip);
qiuFaXiangLiang(
getTriangles()[index].a,
getTriangles()[index].b,
getTriangles()[index].c,
flat_3_temp);
float dotval=DotProduct(flat_3_flip,flat_3_temp);
if(dotval<0){
//点积为负值
return false;
}else
//点积为正值
return true;
}else {
positi=position[0]|position[1]|position[2];
//不共面并且没有在后面的点!!
if(!positi[2])
{
cout<<"前面"<<endl;
return true;
}
//不共面没有前面的点
else if(!positi[1])
{
cout<<"后面"<<endl;
return false;
}else
{
//不共面,既有前面的点,也有后面的点。
cout<<"被分割的面"<<endl;
divied=true;
return false;
}
}
}
//函数功能:从所有的备选三角形列表中找到一个最佳的分割平面。
int getTheBestDivider(vector<int> TheDividerList,bool &found, TheTreeObect obj){
cout<<"×××××××××寻找最佳分割面开始××××××××××××××"<<endl;
cout<<"当前的树深为"<<endl;
cout<<TreeDepth<<endl;
cout<<"要检测的三角集合为:"<<endl;
outPutSanJiaos(obj.getTriangles(),obj.getN());
//定义评估数组
int *pingguvalue=new int[TheDividerList.size()];
//是否找到
found=false;
//定义最佳评估值
int theOptimizedValue;
//最佳的评估值对应的三角形编号(对应于theDividerList)
int theOpTriagl;
//评估值是否初始化
bool IsInit=false;
//判断是否为凸空间,默认为凸
bool AllFront=true;
bool AllBack=true;
for(int flip=0;flip<TheDividerList.size();flip++){
cout<<"-------------------第"<<flip<<"个分割面评估值检测开始-------------------"<<endl;
cout<<"第"<<flip<<"个待定分割面为"<<endl;
cout<<"第"<<TheDividerList[flip]<<"个三角形"<<endl;
outPutSanjiao(obj.getTriangles()[TheDividerList[flip]]);
int N_FRONT=0;
int N_BACK=0;
int N_DIVIDE=0;
if(
!IsTriangle(
obj.getTriangles()[TheDividerList[flip]].a,
obj.getTriangles()[TheDividerList[flip]].b,
obj.getTriangles()[TheDividerList[flip]].c
)
)
{
cout<<"它不是一个平面!"<<endl;
continue;
}else
{
cout<<"它是一个平面!"<<endl;
}
for(int index=0;index<obj.getN();index++){
bool front;
bool same;
bool divided;
front=IsFomFront(obj,index,flip,same,divided);
if(divided){
N_DIVIDE++;
AllBack=false;
AllFront=false;
}
else if(front){
AllBack=false;
N_FRONT++;
}else {
N_BACK++;
AllFront=false;
}
}
//不是所有的平面都在后面,也不是都在前面
if(!AllBack&&!AllFront){
cout<<"找到了这样的平面";
found=true;
}
else{
cout<<"没有找到!";
found=false;
}
cout<<"在它前面的三角形个数为"<<N_FRONT<<endl;
cout<<"在它后面的三角形个数为"<<N_BACK<<endl;
cout<<"被它分割的三角形个数为"<<N_DIVIDE<<endl;
//说明需要可以找到这样的分割面
//found=true;
pinggu_value[flip]=fabs(N_FRONT-N_BACK)+N_DIVIDE;
cout<<"评估值为"<<pinggu_value[flip]<<endl;
if(!IsInit){
theOpTriagl=flip;
theOptimizedValue=pinggu_value[flip];
IsInit=true;
}
//没有初始化并且小于目前的评估值
else if(pinggu_value[flip]<theOptimizedValue){
theOpTriagl=flip;
theOptimizedValue=pinggu_value[flip];
}
cout<<"评估结果为:"<<endl;
cout<<"树深为"<<endl;
cout<<TreeDepth<<endl;
cout<<"要检测的三角集合为:"<<endl;
outPutSanJiaos(obj.getTriangles(),obj.getN());
if(AllBack){
cout<<"它在所有平面的后面"<<endl;
}
else if(AllFront
这里面有分割多边形,和判断平面位置关系两个函数
最新推荐文章于 2020-11-25 12:15:45 发布
这篇博客总结了多边形分割算法的两种方法,包括原有的直接假设交点和新的求交点循环序列算法,并探讨了如何将多边形转化为三角形。同时,介绍了位置判断算法,通过共面和方向判断来确定点的位置关系。
摘要由CSDN通过智能技术生成