背景:需要根据一条已知线段,标记其边长,要求标记位置为多边形内部,标记内容为边长长度,使用宋体标记。
1、代码解析
首先,为满足标记在多边形内部,需要先计算多边形的排序为顺时针还是逆时针,若为顺时针,则沿着前进方向的右侧标记,若为逆时针,沿着前进方向的左侧标记边长文字。
判断多边形顺逆时针,用的是有向面积法。有向面积大于0则为逆时针排序,反之有向面积小于0时,则为顺时针排序。
static void BiaoJi(std::vector<CString>& dis,
std::vector<AcGePoint2d>& positionC, std::vector<double>& angle,
std::vector<AcGePoint2d> pt, int num)
{
//有向面积法,正-逆时针,负-顺时针
double A = 0;
for (int i = 0; i < num - 1; i++)
{
A += pt[i].x * pt[i + 1].y - pt[i + 1].x * pt[i].y;
}
for (int i = 0; i < num - 1; i++)
{
//获取每条边的极角值(弧度值)
double angle1;
double pi = 4 * atan(1);
angle1 = atan2(pt[i + 1].y - pt[i].y, pt[i + 1].x - pt[i].x);
if (angle1 < 0)
{
angle1 += 2 * pi;
}
int bb = 0, cc = 0, dd = 0;
if (angle1 > pi / 2 && angle1 <= 1.5 * pi)
{
bb = 1;
}
if (angle1 > 2 * pi)
{
cc = 1;
}
if (cc == 1 || bb == 1)
{
dd = 1;
}
//处理文字方向
while (dd == 1)
{
if (angle1 > pi / 2 && angle1 <= 1.5 * pi)
{
angle1 += pi;
bb = 1;
}
else
{
bb = 0;
}
if (angle1 > 2 * pi)
{
angle1 -= 2 * pi;
cc = 1;
}
else
{
cc = 0;
}
if (bb == 1 || cc == 1)
{
dd = 1;
}
else
{
dd = 0;
}
}
angle.push_back(angle1);
//计算距离值
double d = pt[i].distanceTo(pt[i + 1]);
CString a;
a.Format(_T("%.2f"), d);
dis.push_back(a);
//计算插入点位置
double x1, y1;
x1 = pt[i].x + pt[i + 1].x;
y1 = pt[i].y + pt[i + 1].y;
AcGeVector2d v = pt[i + 1] - pt[i];
AcGeVector2d v2 = v.normalize();
x1 /= 2;
y1 /= 2;
AcGePoint2d pc(x1, y1);//线段中点坐标
AcGePoint2d pz = pc + v2 * 0.2;//距离中点0.5米沿线段方向的坐标
AcGePoint2d pE;
if (A > 0)
{
//逆时针旋转90度
AcGeVector2d vc1 = pz - pc;
AcGeVector2d vc12(-vc1.y, vc1.x);
pE = pc + vc12;
}
if (A < 0)
{
//顺时针旋转90度
AcGeVector2d vc1 = pz - pc;
AcGeVector2d vc12(vc1.y, -vc1.x);
pE = pc + vc12;
}
positionC.push_back(pE);
}
}
然后,使用atan2函数获取线段的极角值,并确保当边长极角大于90度和小于270度时,将文字标注旋转角加上180度,相加后保持在360度之内,超出则减去360度。
文字插入点位置为边长中点,沿边长前进方向0.2米处的点,将其按顺逆时针旋转90度后得到插入点位置。
距离计算,使用distanceTo函数即可。
146

被折叠的 条评论
为什么被折叠?



