折线的等分点标注法和等间隔标注法
折线的标注法有两种,一种是给定需要标记的点数进行标记,另外一种是给定标记的两点之间的间隔进行标记
首先建立点的结构体
struct polyline {
int num;//折线上的点的数目
int point_num;//等分点标注法需要标记的点数
float space;//等间隔标注法的间隔
double coord[1000][2];//折线上点的坐标
};
等分点标注法
等分点标注法首先需要计算两个点之间的间隔,以便后续的计算。首先确定起始点为起始坐标,计算该点与下一个点之间的距离是不是大于或者等于间隔,如果是,计算x,y值,并且将起始点的坐标改变为计算所得的x,y值;如果距离小于间隔,则用间隔减去这两个点之间的距离,并且将起始点坐标改变为下一个坐标点的坐标。这样来进行逐条线段的处理,得到标注点的坐标。
/************************************************************
*函数名:method_A
*主要功能:对单个的一条折线,使用等分点标注法进行标注
*输入参数说明:单个的一条折线的结构体
*输出说明:会将计算所得的标注点的x,y逐个输出
*返回值:无返回值
case:
pyline要求标记2个点,坐标依次是(0.0,0.0)、(1.0,1.0) 、(4.0,4.0)
method_A(pyline);
会输出:标记点坐标为:
1.333333 1.333333
2.666667 2.666667
***************************************************************/
int method_A(polyline pyline) {
double line_lenth = 0;
//计算折线的总长度
for (int i = 1; i < pyline.num; i++) {
line_lenth += sqrt(pow(pyline.coord[i][0] - pyline.coord[i - 1][0],2)+pow(pyline.coord[i][1]-pyline.coord[i-1][1],2));//计算总的长度
}
double distance = line_lenth / ((__int64)pyline.point_num + 1);//计算每一段的长度
double x1 = pyline.coord[0][0];
double y1 = pyline.coord[0][1];//起始点的坐标
double cur_distance = distance;
int out_point = 0;//统计输出点
cout << "标记点坐标为:" << endl;
for (int j = 1; j < pyline.num; j++) {
double x2 = pyline.coord[j][0];
double y2 = pyline.coord[j][1];
//逐条线段处理
while (1) {
double line_distance = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
//当前线段长度不小于每一段的长度
if (line_distance >= cur_distance) {
double x = (x2 - x1) * cur_distance / line_distance + x1;
double y = (y2 - y1) * cur_distance / line_distance + y1;//计算x,y的值
out_point++;
if (out_point > pyline.point_num) {
break;
}
cout << x << ' ' << y << endl;
x1 = x;
y1 = y;//改变起始点的坐标
cur_distance = distance;
}
//当前线段长度不足时,考虑下一条线段
else {
x1 = x2;
y1 = y2;//改变起始点的坐标
cur_distance -= line_distance;//长度要减去之前线段的长度
break;
}
}
}
return 0;
}
等间隔标注法
/************************************************************
*函数名:method_B
*主要功能:对单个的一条折线,使用等间隔标注法进行标注
*输入参数说明:单个的一条折线的结构体
*输出说明:会将计算所得的标注点的x,y逐个输出
*返回值:无返回值
case:
pyline要求间隔是2.0,坐标依次是(0.0,0.0)、(2.0,0.0) 、(5.0,0.0)
method_B(pyline);
会输出:标记点数量为:3
标记点坐标为:
0.5 0
2.5 0
4.5 0
***************************************************************/
int method_B(polyline pyline){
double line_lenth = 0;
//计算折线的总长度
for (int i = 1; i < pyline.num; i++) {
line_lenth += sqrt(pow(pyline.coord[i][0] - pyline.coord[i - 1][0], 2) + pow(pyline.coord[i][1] - pyline.coord[i - 1][1], 2));
}
double division = line_lenth / pyline.space;
double distance = 0;//最边上的点与端点的距离
//如果能够整除,distance就是间隔的一半,也就是说先从一半开始标记
if ((int)division-division==0) {
distance = pyline.space / 2.0;
}
//如果不能整除,就用下面的公式,计算distance
else {
distance = (line_lenth - (__int64)((int)(line_lenth / pyline.space)) * (__int64)pyline.space) / 2.0;
}
cout << "标记点数量为:"<<(int)division+1<<endl;
double x1 = pyline.coord[0][0];
double y1 = pyline.coord[0][1];
cout << "标记点坐标为:" << endl;
int out_point = 0;//统计输出点
for (int j = 1; j < pyline.num; j++) {
double x2 = pyline.coord[j][0];
double y2 = pyline.coord[j][1];
while (1) {
//起始距离为我们前面计算的distance,之后变为正常距离
double line_distance = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
if (line_distance >= distance) {
double x = (x2 - x1) * distance / line_distance + x1;
double y = (y2 - y1) * distance / line_distance + y1;
out_point++;
cout << x << ' ' << y << endl;
x1 = x;
y1 = y;
distance = pyline.space;//变为正常间隔
}
//当前线段长度不足时,考虑下一条线段
else {
x1 = x2;
y1 = y2;
distance -= line_distance;
break;
}
}
}
return 0;
}
结语
等间隔标注法其实与等分点标注法有相同之处,只是端点两边的处理不太一样。如果线段长度能够整除间隔,那么最边上的点与端点的距离就是间隔的一半,否则就是余数的一半。计算得到最边上点与端点的距离后,就先以这个距离来标记第一个点,标记完第一个点后,剩下的过程与等分点标注法便一样了。