#include "StdAfx.h" #include "ObjFill.h" #include "GlobalFunction.h" #include "GlobalDrawMgr.h" #include "LogMgr.h" #define MAX_FILL_LINE_LEN 500 //最大填充范围 CObjFill::CObjFill(vector &Vec) :m_SequentialPointVec(Vec) { } CObjFill::~CObjFill(void) { } //根据obj 传入的数据点来创建填充数据 void CObjFill::CreatFill(vector> &LinesVec,DbRect rect) { if(m_FillPar.bFill ==false) return; Dbxy Pt1,Pt2,Offset; int ScanTimes = 0; //获取用于扫描的线(Pt1,Pt2是第一条线),并计算出扫描线的次数 GetScanLine(rect,Pt1,Pt2,Offset,ScanTimes); //往回缩一点,照顾第一条线 Pt1.x -= Offset.x/2; Pt2.x -= Offset.x/2; Pt1.y -= Offset.y/2; Pt2.y -= Offset.y/2; //调整第一条线,保证多区域之间的间隔一致 for(int i=0;i IntersectionVec; if(GetIntersection(LinesVec,Pt1,Pt2,IntersectionVec,rect)) { //对计算出的交点排序 SortIntersection(IntersectionVec); //保存扫描结果 SaveScanResult(IntersectionVec); } //扫描线偏移 Pt1.x += Offset.x; Pt1.y += Offset.y; Pt2.x += Offset.x; Pt2.y += Offset.y; } } #if 1//创建 //获取用于扫描的线(ScanTimes 是扫描线偏移的次数) void CObjFill::GetScanLine(DbRect rect,Dbxy &Pt1,Dbxy &Pt2,Dbxy &Offset,int &ScanTimes) { //创建一条足够长的线段 double R = MAX_FILL_LINE_LEN;//这里会限制填充的范围 Dbxy CenterPt(rect.L,rect.T); Pt1.y = Pt2.y = rect.T; Pt1.x = rect.L-R; Pt2.x = rect.R+R; double FillGap = m_FillPar.m_FillGap;//填充间隔 Dbxy Pt(Pt1.x,Pt1.y-FillGap);//用来计算扫描线每次的偏移 //旋转扫描线 double Angle = _360ToAngle(m_FillPar.m_FillAngle); Pt1 = RotatoPt(Pt1,Angle,CenterPt); Pt2 = RotatoPt(Pt2,Angle,CenterPt); Pt = RotatoPt(Pt,Angle,CenterPt); double len = CalDistance(Dbxy(rect.L,rect.T),Dbxy(rect.R,rect.B)); ScanTimes = len/FillGap; //每次扫描线的偏移 Offset.x = Pt.x - Pt1.x; Offset.y = Pt.y - Pt1.y; } //计算连续线段和pt1,pt2 线段的交点(结果保存到IntersectionVec) //交点需要在rect 范围内 bool CObjFill::GetIntersection(vector> &LinesVec,Dbxy pt1,Dbxy pt2,vector &IntersectionVec,DbRect rect) { IntersectionVec.clear(); if(pt1.x>3.66 && pt1.x<4.44) { int a = 0; } vector>::iterator iter = LinesVec.begin(); vector>::iterator iter_end = LinesVec.end(); for(;iter!=iter_end;iter++) { int size = (*iter).size(); for(int i=0;i7.974 && u1.x<7.976)&&(u2.x>4.04 && u2.x<4.06)) { int a=0; } //处理正好是端点的情况 if(dot_online_in(u1,pt1,pt2) && dot_online_in(u2,pt1,pt2))//两个点都在pt1,pt2 上 { //将扫描线稍微回撤一点点再算一次,过滤掉这种情况 double offset = 0.0001; pt1.x -= offset; pt2.x -= offset; pt1.y -= offset; pt2.y -= offset; //递归函数(注意) return GetIntersection(LinesVec,pt1,pt2,IntersectionVec,rect); } else if(dot_online_in(u1,pt1,pt2))//第一个点在pt1,pt2 上 { continue; } else if(dot_online_in(u2,pt1,pt2))//第二个点在pt1,pt2 上 { //后一条线段的第二个点在另外一端时,才算交点 if((i+2) &IntersectionVec) { if(m_FillPar.m_FillAngle<=45) { sort(IntersectionVec.begin(),IntersectionVec.end(),CompareDbxyByX); } else { sort(IntersectionVec.begin(),IntersectionVec.end(),CompareDbxyByY); } } //保存扫描结果 void CObjFill::SaveScanResult(vector &IntersectionVec) { int size = IntersectionVec.size(); int idx = 1; for(int i=1;i