Vector自定义排序规则 实现多边形顺时针排序

yilin57 2011-01-07 07:39:41
我想对存储在Vector中的自定义类型元素进行排序,用了仿函数来定义排序规则,即实现对多边形的顶点进行顺时针排序,小坐标的数据可以正常排序,换大坐标的大数据量,排序失效。

之前报错:invalid < ,之后通过将涉及两浮点数比较大小的部分改为:fabs(A-B)<FLT_EPSILON后,不提示该错误!
但排序仿函数失效!
问题:
是浮点数精度引起的呢?还是本身排序规则中返回true或者false的时候不符合标准库规范?这两种考虑,都试着改了很多次,还是不知道到底什么原因。

相关代码如下:

...
std::sort(V1.m_voronoi_cell.begin(), V1.m_voronoi_cell.end(), sort_vector_op(V1.m_pt));
...

class sort_vector_op
{
public:
sort_vector_op(c2ga::normalizedPoint center_point)
{
float biao_gan_x = center_point.m_c[0];
float biao_gan_y = center_point.m_c[1]+100;
float m_ni = 0.5*(biao_gan_x*biao_gan_x + biao_gan_y*biao_gan_y);
p0 = c2ga::normalizedPoint(c2ga::normalizedPoint_e1_e2_ni_nof1_0,biao_gan_x, biao_gan_y, m_ni);

float m_Origin_x = center_point.m_c[0];
float m_Origin_y = center_point.m_c[1];
m_ni = 0.5*(m_Origin_x*m_Origin_x + m_Origin_y*m_Origin_y);
m_Origin = c2ga::normalizedPoint(c2ga::normalizedPoint_e1_e2_ni_nof1_0, center_point.m_c[0], center_point.m_c[1], m_ni);
}

bool operator()( const m_voronoi &arg1,const m_voronoi &arg2 )const
{
c2ga::normalizedPoint V1 = arg1.vertex;
c2ga::normalizedPoint V2 = arg2.vertex;

c2ga::normalizedPoint pV1 = Minus(m_Origin, V1);
c2ga::normalizedPoint pV2 = Minus(m_Origin, V2);
c2ga::normalizedPoint bp = Minus(m_Origin, p0);
e2ga::vector V_A ;
V_A.set(e2ga::vector_e1_e2,pV1.e1(),pV1.e2());
e2ga::vector V_B ;
V_B.set(e2ga::vector_e1_e2,pV2.e1(),pV2.e2());
e2ga::vector OUT_bp;
OUT_bp.set(e2ga::vector_e1_e2,bp.e1(),bp.e2());

// note [1/7/2011 Eline]
//e2ga::mv MV_Oa = e2ga::op(OUT_bp,V_A);
//e2ga::mv MV_Ob = e2ga::op(OUT_bp,V_B);
//float OA = MV_Oa.m_c[0];
//float OB = MV_Ob.m_c[0];//取bivector不确定是取第几个,应该就是这个~
// end_note [1/7/2011 Eline]

e2ga::mv MV_a = unit_e(OUT_bp)<< unit_e(V_A);
e2ga::mv MV_b = unit_e(OUT_bp)<< unit_e(V_B);
float A = MV_a.m_c[0];
float B = MV_b.m_c[0];

//两点同在右边
if (( fabs(V1.m_c[0] - m_Origin.m_c[0]) > FLT_EPSILON) && (fabs(V2.m_c[0] - m_Origin.m_c[0]) > FLT_EPSILON))
{

//if (A > B)
////if (fabs(A - B) > FLT_EPSILON)
//{
// return true;
//}
//else
//{
// return false;
//}
// note [1/7/2011 Eline]

return MV_a.m_c[0] > MV_b.m_c[0];
}
//两点同在左边
else if((fabs(V1.m_c[0] - m_Origin.m_c[0]) < FLT_EPSILON) && (fabs(V2.m_c[0] - m_Origin.m_c[0]) < FLT_EPSILON))
{
//if (A > B || A == B)
////if (fabs(A - B) > FLT_EPSILON || fabs(A - B) == FLT_EPSILON)
//{
// return false;
//}
//else
//{
// return true;
//}
// note [1/7/2011 Eline]

return MV_a.m_c[0] < MV_b.m_c[0];
}
//两个点在不同象限

//第一个点在第一象限
if ((fabs(V1.e1()-m_Origin.e1())> FLT_EPSILON)&& (fabs(V1.e2() - m_Origin.e2()) < FLT_EPSILON))
{
return true;
}
//第二个点在第一象限
else if ((fabs(V2.e1()-m_Origin.e1()) > FLT_EPSILON)&& (fabs(V2.e2() - m_Origin.e2())< FLT_EPSILON))
{
return false;
}
//第一个点在第四象限
else if ((fabs(V1.e1()-m_Origin.e1()) > FLT_EPSILON) && (fabs(V1.e2()- m_Origin.e2()) < FLT_EPSILON))
{
return true;
}
//第二个点在第四象限
else if ((fabs(V2.e1()-m_Origin.e1())>FLT_EPSILON) && (fabs(V2.e2()-m_Origin.e2()) < FLT_EPSILON))
{
return false;
}
//第一个点在第三象限
else if ((fabs(V1.e1()-m_Origin.e1()) < FLT_EPSILON) && (fabs(V1.e2()-m_Origin.e2()) < FLT_EPSILON))
{
return true;
}
//第二个点在第三象限
else if ((fabs(V2.e1()-m_Origin.e1()) < FLT_EPSILON) && (fabs(V2.e2()-m_Origin.e2()) < FLT_EPSILON))
{
return false;
}
//第一个点在第二象限
else if ((fabs(V1.e1()-m_Origin.e1()) < FLT_EPSILON) && (fabs(V1.e2()-m_Origin.e2()) > FLT_EPSILON))
{
return true;
}
//第二个点在第二象限
else
{
return false;
}
}

public:
c2ga::normalizedPoint p0; //base

c2ga::normalizedPoint m_Origin;
};
...全文
571 7 打赏 收藏 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zy020118 2011-01-07
  • 打赏
  • 举报
回复
FLT_EPSILON本质意义是定义的大于0的最小正数,所以考虑精度问题时,比较浮点数A和B等价如下
A == B ==> fabs(A - B) < FLT_EPSILON
A < B ==> (B - A) >= FLT_EPSILON
A > B ==> (A - B) >= FLT_EPSILON
yilin57 2011-01-07
  • 打赏
  • 举报
回复
成功!谢谢你!自己太马虎了。。。不过浮点数比大小精度问题这个还是要来深究一下~先谢过啦
yilin57 2011-01-07
  • 打赏
  • 举报
回复
我弄错了,先把这个改过来!
zy020118 2011-01-07
  • 打赏
  • 举报
回复
fabs求浮点数x的绝对值,所以肯定是不一样的
yilin57 2011-01-07
  • 打赏
  • 举报
回复
不一样么?不是相当于A-B<0么?
zy020118 2011-01-07
  • 打赏
  • 举报
回复
fabs(A-B)<FLT_EPSILON这个的作用是判断两个数是否相等,和 A < B 不一样吧
yilin57 2011-01-07
  • 打赏
  • 举报
回复
在线等
内容概要:本文研究了基于PSCAD与MATLAB联合仿真平台的多区距离保护与智能故障定位协同方法,旨在提升高压输电线路在复杂运行条件下的保护精度与故障定位能力。研究融合全周期滑动DFT相量提取技术与Fortescue对称分量变换,构建适用于多区段输电线路的距离保护算法,并引入智能故障定位机制,实现故障区段的快速识别与精确定位。通过PSCAD进行电磁暂态建模与仿真,生成高保真故障数据,再利用MATLAB完成信号处理、保护判据计算与故障定位算法开发,充分发挥二者在高精度建模与高效算法实现方面的互补优势。研究覆盖系统建模、信号处理、保护逻辑设计、定位算法优化及联合仿真验证全流程,显著提升了距离保护的动作可靠性与故障定位的准确性。; 适合人群:具备电力系统继电保护基础知识,熟悉PSCAD和MATLAB仿真工具,从事电力系统自动化、继电保护算法开发或智能电网技术研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于高压输电线路的继电保护系统设计与优化;②用于开发高精度、自适应的智能故障定位算法;③实现PSCAD与MATLAB在复杂电力系统仿真与分析中的协同应用,提升科研与工程项目的开发效率。; 阅读建议:读者应结合文中提供的仿真模型与算法代码,动手实践联合仿真流程,重点关注DFT相量提取、对称分量变换的应用以及保护与定位算法的逻辑实现,建议在PSCAD中修改故障条件,在MATLAB中调试算法参数,以深入理解方法的鲁棒性与适应性。

65,214

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧