# 任意多边形面积计算（用于任意水位的非规则河道截面积计算）

//堰槽坐标定义
typedef struct
{
double x;
double y;
}WeirCoorType;

//任意多边形面积计算
double CLASS_NAME::PolygonAreaCalculation(WeirCoorType *pWeirCoor, WORD CoorCnt)
{
double sum0 = 0;
double square;

//这个多边形计算代码如此简单，可以计算任意的多边形，就算是弧形都行，只要你输入坐标点就行
for (int i = 0; i < CoorCnt - 1; i++)
{
sum0 += (pWeirCoor[i].x * pWeirCoor[i + 1].y - pWeirCoor[i + 1].x * pWeirCoor[i].y);
}
square = (fabs(sum0 + (pWeirCoor[CoorCnt - 1].x * pWeirCoor[0].y) - (pWeirCoor[0].x * pWeirCoor[CoorCnt - 1].y))) / 2;

return square;
}

//计算交点的X值
double CLASS_NAME::CalculateIntersectionX(WeirCoorType *pWeirCoor1, WeirCoorType *pWeirCoor2, double y)
{
double ftemp;
WeirCoorType *pMaxCoor, *pMinCoor;

if (pWeirCoor1->y == pWeirCoor2->y) //Y轴一样，不允许的，随便输出一个X轴
{
SYS_LOG.Write(__FILE__ + __LINE__ + " \t：不允许2个坐标的Y轴一样\r\n");
return pWeirCoor1->x;
}
else if (pWeirCoor1->y > pWeirCoor2->y)
{
pMaxCoor = pWeirCoor1;	//Y轴大的点
pMinCoor = pWeirCoor2;	//Y轴小的点
}
else
{
pMaxCoor = pWeirCoor2;	//Y轴大的点
pMinCoor = pWeirCoor1;	//Y轴小的点
}
if (y >= pMaxCoor->y) return pMaxCoor->x;	//大于大的点
if (y <= pMinCoor->y) return pMinCoor->x;	//小于小的点
//斜线，并且处于中间
ftemp = ((pMaxCoor->y - y) * (pMaxCoor->x - pMinCoor->x)) / (pMaxCoor->y - pMinCoor->y);

ftemp = pMaxCoor->x - ftemp;

return ftemp;
}

//线程-运行核心
System::Void CLASS_NAME::BackgroundWorker_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e)
{
double ftemp;
double Y_Inc = 0.1;	//Y轴增量
WORD i;
double X;
int Status;
WORD count;
WORD StartIndex;
int n;
char buff[32];

WeirCoorType TempWeirCoor1[256];
try
{
this->VarY = 0;
for (n = 0; n < 256; n++)
{
//WeirCoorType WeirCoor1[9] = { {0,0}, {25,0}, {25,50}, {75,50},{75,0}, {90,0},{100,0}, {100,100},{0,100}};

//坐标必须按照顺序，从左上角，左下角，右下角，右上角顺序，X轴依次增加，左上角与右上角Y轴相等并且最大
//WeirCoorType WeirCoor1[9] = { { 0, 100 }, { 0, 0 }, { 25, 0 }, { 25, 50 }, { 75, 50 }, { 75, 0 }, { 100, 0 }, { 100, 100 }};

//寻找Y轴交点坐标

i = 0;
count = 0;
for (int j = 0; j < this->WeirCoorNum / 2; j++)		//循环寻找交点-一对
{
//从第一个坐标开始，先寻找Y值对应的X坐标
for (; i < (this->WeirCoorNum - 1); i++)
{
if (this->pWeirCoorBuff[i].y >= this->VarY && this->pWeirCoorBuff[i + 1].y < this->VarY) //左边交点
{
USER_DEBUG.Printf("左交点：%f,%f~%f,%f\r\n", this->pWeirCoorBuff[i].x, this->pWeirCoorBuff[i].y, this->pWeirCoorBuff[i + 1].x, this->pWeirCoorBuff[i + 1].y);

//计算交点坐标
X = this->CalculateIntersectionX(&this->pWeirCoorBuff[i], &this->pWeirCoorBuff[i + 1], this->VarY);
USER_DEBUG.Printf("左交点：(%f,%f)\r\n", X, this->VarY);

TempWeirCoor1[count].x = X;
TempWeirCoor1[count].y = this->VarY;
count++;
StartIndex = i + 1;

break;
}
}

//从第一个坐标开始，先寻找Y值对应的X坐标
for (; i < (this->WeirCoorNum - 1); i++)
{
if (this->pWeirCoorBuff[i].y < this->VarY && this->pWeirCoorBuff[i + 1].y >= this->VarY) //右边交点
{
USER_DEBUG.Printf("右交点：%f,%f~%f,%f\r\n", this->pWeirCoorBuff[i].x, this->pWeirCoorBuff[i].y, this->pWeirCoorBuff[i + 1].x, this->pWeirCoorBuff[i + 1].y);

//计算交点坐标
X = this->CalculateIntersectionX(&this->pWeirCoorBuff[i], &this->pWeirCoorBuff[i + 1], this->VarY);
USER_DEBUG.Printf("右交点：(%f,%f)\r\n", X, this->VarY);

for (int k = StartIndex; k <= i; k++)
{
TempWeirCoor1[count].x = this->pWeirCoorBuff[k].x;
TempWeirCoor1[count].y = this->pWeirCoorBuff[k].y;
count++;
}

TempWeirCoor1[count].x = X;
TempWeirCoor1[count].y = this->VarY;
count++;

break;
}
}

if (i >= this->WeirCoorNum - 1) break;
}

this->SelectCoorCount = count;  //选择的点数量
memcpy(this->pSelectWeirCoor1, TempWeirCoor1, sizeof(WeirCoorType) * count);
this->mBackgroundWorker->ReportProgress(1);	//状态改变

//打印最终的坐标
USER_DEBUG.Printf("多边形坐标：");
for (i = 0; i < count; i++)
{
USER_DEBUG.Printf("%f,%f \t", TempWeirCoor1[i].x, TempWeirCoor1[i].y);
}
USER_DEBUG.Printf("\r\n");

//WeirCoorType WeirCoor1[8] = { {0,0}, {100,0}, {100,100},{1,100}};

//任意多边形面积计算
ftemp = this->PolygonAreaCalculation(TempWeirCoor1, count);

USER_DEBUG.Printf("面积：%f\r\n", ftemp);
this->SectionalArea = ftemp;	//最终的截面积
this->SectionalAreaBuff[n] = this->SectionalArea; //截面积写入全局缓冲区中

this->VarY += this->VerticalResVal;
if (this->VarY > this->pWeirCoorBuff[0].y)
{
USER_DEBUG.Printf("垂直高度超出范围了，退出！\r\n");
break;
}
Sleep(20);
}

ftemp = this->SectionalArea;
for (; n < 256; n++)	//补充不足256个截面数据，后面截面积固定
{
this->SectionalAreaBuff[n] = ftemp;
ftemp += 0.00001; //截面积只能增大，不能不变，有效位数5位小数自增
}

//生成datatable
this->mDataTable->Rows->Clear();	//清空行
for (int i = 0; i < 256; i++)		//循环添加行
{
DataRow ^dr = this->mDataTable->NewRow();//新建行
sprintf_s(buff, 31, "%.5f", this->SectionalAreaBuff[i]);
dr[0] = CharToString(buff);

}

}
catch (Exception ^e1)
{
SYS_LOG.Write(__FILE__ + __LINE__ + "\t:" + e1->Message + e1->StackTrace);
}
}


• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120