#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 && iGetAngle(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;is) { 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(l0BinarySearch(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(l0BinarySearch(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(tDistance(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); //构建新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;iGetCount();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) //根据骨骼线索引号生成GPline对象 { 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; } //生成骨骼线数组 int GPlineSkeleton::GetSkeletonCurves(std::vector& 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(); } //生成最长骨骼线,返回为GPline指针,需要外部删除 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; //获得当前线的曲线长度 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; } //比较获得最长线 if(nFindIndex < 0) { nFindIndex = i; dLength = curLen; } else { if(dLength < curLen) { dLength = curLen; nFindIndex = i; } } } return CreateSkeletonCurve(nFindIndex); }