You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

382 lines
7.4 KiB
C++

1 month ago
#include "stdafx.h"
#include "Skeleton.h"
#include "PublicFunctions.h"
CPublicFunctions g_bf;
CPublicFunctions* AfxGetBaseFunction()
{
return &g_bf;
}
GPlineSkeleton::GPlineSkeleton()
{
}
GPlineSkeleton::~GPlineSkeleton()
{
Clear();
}
void GPlineSkeleton::Clear(void)
{
m_skeletonLines.clear();
}
double GPlineSkeleton::GetCurveAngle(GPline& curve, double l, double step)
{
//int i=of.BinarySearch(l,curve.num,curve.l);
//if(i>0 && i<curve.num-1)
// return _GetAngle(curve.x[i-1],curve.y[i-1],curve.x[i],curve.y[i],curve.x[i+1],curve.y[i+1]);
//return 0;
GPoint3D p1,p2,p3;
curve.GetCoordinate(l-step,p1.x0,p1.y0,p1.z0);
curve.GetCoordinate(l,p2.x0,p2.y0,p2.z0);
curve.GetCoordinate(l+step,p3.x0,p3.y0,p3.z0);
return AfxGetBaseFunction()->GetAngle(p1.x0,p1.y0,p2.x0,p2.y0,p3.x0,p3.y0);
}
int GPlineSkeleton::GetMinAngle(GPline &curve,double step)
{
int i,j;
double t,s;
j=0;
s=0;
for(i=1;i<curve.GetCount()-1,++i)
{
t=GetCurveAngle(curve,curve.L(i)+1e-10,step*0.1);
t=fabs(t);
if(t>s)
{
s=t;
j=i;
}
}
return j;
}
int GPlineSkeleton::Create(GPline &curve,double step)
{
list.clear();
int i,j,k;
j=GetMinAngle(curve,step);
double l0,lmax;
GPoint3D point;
i=j;
point.x0=curve.X(i);
point.y0=curve.Y(i);
list.push_back(point);
lmax=curve.L(curve.GetCount()-1);
l0 =curve.L(j)+step;
while(l0<lmax)
{
i++;
while(l0<curve.L(i) )
{
k=AfxGetBaseFunction()->BinarySearch(l0,curve.num,curve.l);
point.x0=AfxGetBaseFunction()->LineValue(l0,curve.l+k,curve.x+k);
point.y0=AfxGetBaseFunction()->LineValue(l0,curve.l+k,curve.y+k);
list.push_back(point);
l0+=step;
}
point.x0=curve.x[i];
point.y0=curve.y[i];
list.push_back(point);
}
i=0;
point.x0=curve.X(i);
point.y0=curve.Y(i);
list.push_back(point);
lmax=curve.l[j];
l0=curve.l[0]+step;
while(l0<lmax)
{
i++;
while(l0<curve.l[i])
{
k=AfxGetBaseFunction()->BinarySearch(l0,curve.num,curve.l);
point.x0=AfxGetBaseFunction()->LineValue(l0,curve.l+k,curve.x+k);
point.y0=AfxGetBaseFunction()->LineValue(l0,curve.l+k,curve.y+k);
list.push_back(point);
l0+=step;
}
point.x0=curve.x[i];
point.y0=curve.y[i];
list.push_back(point);
}
point.x0=curve.x[j];
point.y0=curve.y[j];
list.push_back(point);
list.AddHead(point);
return 1;
}
void GPlineSkeleton::GetFirstTriangle(CSkeletonTriangle &tri)
{
tri.p1=list.GetHeadPosition();
tri.p2=tri.p1;
list.GetNext(tri.p2);
tri.p3=list.GetTailPosition();
}
int GPlineSkeleton::GetNext(CSkeletonTriangle &tri)
{
if(tri.p2==tri.p3 || tri.p1==NULL || tri.p2==NULL || tri.p3==NULL)
{
return 0;
}
CSklTriPoint pp;
pp.p1=list.GetAt(tri.p1);
pp.p2=list.GetAt(tri.p2);
pp.p3=list.GetAt(tri.p3);
SKLINE* fw = &m_skeletonLines.back();
pp.Write23(fw);
POSITION p,pm,prev,next,pold;
pm=NULL;
double t,s;
s=1e300;
pold=tri.p1;
p=tri.p2; list.GetNext(p); next=p;
prev=tri.p3; list.GetPrev(prev);
if(p==NULL)return 0;
while(p!=tri.p3)
{
pp.p1=list.GetAt(p);
t=pp.Value();
if(t<s)
{
s=t;
pm=p;
}
list.GetNext(p);
if(p==NULL)
{
::AfxMessageBox("Bad process");
return 0;
}
}
if(pm==next)
{
tri.p1=tri.p2;
tri.p2=pm;
}
else if(pm==prev)
{
tri.p1=tri.p3;
tri.p3=pm;
}
else
{
pp.Write23(fw);
CSkeletonTriangle tri2,tri1;
tri1=tri;
tri2=tri;
tri1.p1=tri1.p2;
tri1.p2=pm;
tri2.p1=tri2.p3;
tri2.p3=pm;
Trace(tri1);
Trace(tri2);
return 0;
}
return 1;
}
double GPlineSkeleton::CSklTriPoint::Value()
{
return AfxGetBaseFunction()->Distance(p1.x0,p1.y0,p2.x0,p2.y0) +
AfxGetBaseFunction()->Distance(p1.x0,p1.y0,p3.x0,p3.y0);
}
void GPlineSkeleton::CSklTriPoint::Write12(SKLINE *&fw)
{
////fprintf(fw,"%lf,%lf,%lf\n",(p1.x0+p2.x0)*0.5,(p1.y0+p2.y0)*0.5,_Distance(p2.x0,p2.y0,p1.x0,p1.y0));
//fprintf(fw,"%lf,%lf\n",(p1.x0+p2.x0)*0.5,(p1.y0+p2.y0)*0.5);
fw->push_back(GPoint3D((p1.x0+p2.x0)*0.5,(p1.y0+p2.y0)*0.5));
}
void GPlineSkeleton::CSklTriPoint::Write23(SKLINE *&fw)
{
////fprintf(fw,"%lf,%lf,%lf\n",(p2.x0+p3.x0)*0.5,(p2.y0+p3.y0)*0.5,_Distance(p2.x0,p2.y0,p3.x0,p3.y0));
//fprintf(fw,"%lf,%lf\n",(p2.x0+p3.x0)*0.5,(p2.y0+p3.y0)*0.5);
fw->push_back(GPoint3D((p2.x0+p3.x0)*0.5,(p2.y0+p3.y0)*0.5)) ;
}
void GPlineSkeleton::Trace(CSkeletonTriangle &tri)
{
if(tri.p1==NULL || tri.p2==NULL || tri.p3==NULL) return;
#ifndef _GDF_QT
if(!AfxIsValidAddress(tri.p1, sizeof(tri.p1))) return;
if(!AfxIsValidAddress(tri.p2, sizeof(tri.p2))) return;
if(!AfxIsValidAddress(tri.p3, sizeof(tri.p3))) return;
#endif
//if(name.IsEmpty()) fprintf(fw,"Pline\n");
//else fprintf(fw,"Pline.%s\n",name);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SKLINE
m_skeletonLines.push_back(SKLINE());
CSklTriPoint pp;
pp.p1=list.GetAt(tri.p1);
pp.p2=list.GetAt(tri.p2);
pp.p3=list.GetAt(tri.p3);
SKLINE* fw = &m_skeletonLines.back();
pp.Write12(fw);
while(GetNext(tri));
}
void GPlineSkeleton::Trace(GPline* curve, double step)
{
GPline* pc = RemoveRepeatPoint(curve);
Create(*pc,step);
delete pc;
//Create(curve,step);
CSkeletonTriangle tri;
GetFirstTriangle(tri);
Trace(tri);
}
GPline* GPlineSkeleton::RemoveRepeatPoint(GPline* pc)
{
GPline* c = new GPline();// (pc->GetCount());
if(!pc->GetName().empty())
{
string str=pc->GetName();
c->SetName(str);
}
int sel=0;
int j=0;
//c->SetPoint(0, pc->GetPoint(0));
c->AddPoint(pc->GetPoint(0));
j++;
BOOL bEnd=FALSE;
for(int i=1;i<pc->GetCount();i++)
{
sel=i-1;
while(AfxGetBaseFunction()->Distance(pc->X(i),pc->Y(i),pc->X(sel),pc->Y(sel))<1e-6)
{
i++;
if(i>pc->GetCount()-1) { bEnd=TRUE; break; }
}
if(bEnd)
break;
//c->SetPoint(j, pc->GetPoint(i));
c->AddPoint(pc->GetPoint(i));
j++;
}
//c->nPoint=2;
//c->num=j;
//c->GetLocation();
return c;
}
GPline* GPlineSkeleton::CreateSkeletonCurve(int nIndex) //<2F><><EFBFBD>ݹ<EFBFBD><DDB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>GPline<6E><65><EFBFBD><EFBFBD>
{
if(nIndex < 0 || nIndex >= m_skeletonLines.size())
return NULL;
SKLINE* line = &m_skeletonLines[nIndex];
if(line->size() < 2)
return NULL;
GPline* curve = new GPline();
int count = 0;
SKLINE::iterator iter;
for(iter = line->begin(); iter != line->end(); iter ++ )
{
curve->AddPoint(GPoint3D(iter->x0, iter->y0,0));
//curve->x[count] = iter->x0;
//curve->y[count] = iter->y0;
//count ++ ;
}
double removeStep = 0.0001;
curve->RemoveSamePoint(removeStep);
if(curve->GetCount() < 2)
{
delete curve;
return NULL;
}
// curve->GetLocation();
return curve;
}
//<2F><><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int GPlineSkeleton::GetSkeletonCurves(std::vector<GPline*>& curveVec)
{
if(m_skeletonLines.empty() )
return 0;
SKLINE::iterator iter;
for(int i = 0; i < m_skeletonLines.size(); i ++ )
{
GPline* curve = CreateSkeletonCurve(i);
if(curve == NULL)
continue;
curveVec.push_back(curve);
}
return curveVec.size();
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEB3A4><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD>ΪGPlineָ<65><EFBFBD><EBA3AC>Ҫ<EFBFBD>ⲿɾ<E2B2BF><C9BE>
GPline* GPlineSkeleton::CreateLongestCurve()
{
if(m_skeletonLines.empty() )
return NULL;
int nFindIndex = -1;
double dLength = 0;
double curLen;
SKLINE::iterator iter;
SKLINE::iterator prev;
for(int i = 0; i < m_skeletonLines.size(); i ++ )
{
SKLINE* line = &m_skeletonLines[i];
if(line->size() < 2)
continue;
//<2F><><EFBFBD>õ<EFBFBD>ǰ<EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD>
curLen = 0;
prev = line->begin();
iter = prev;
iter++;
for(; iter != line->end(); iter ++ )
{
curLen += AfxGetBaseFunction()->Distance(prev->x0, prev->y0, iter->x0, iter->y0);
prev = iter;
}
//<2F>Ƚϻ<C8BD><CFBB><EFBFBD><EFBFBD><EFBFBD><EEB3A4>
if(nFindIndex < 0)
{
nFindIndex = i;
dLength = curLen;
}
else
{
if(dLength < curLen)
{
dLength = curLen;
nFindIndex = i;
}
}
}
return CreateSkeletonCurve(nFindIndex);
}