Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //---------------------------------------------------------------------------
- #include <math.h>
- #include <float.h>
- #include "UECCore.h"
- #pragma hdrstop
- #include "UCFloatPoint.h"
- #include <Math.hpp>
- //---------------------------------------------------------------------------
- #pragma package(smart_init)
- //---------------------------------------------------------------------------
- void CFloatPoint::RotatePoint(double angle,bool radian)
- {
- double rad;
- if (!radian) rad=(M_PI*angle)/180;
- else rad=angle;
- double cosa=cos(rad),
- sina=sin(rad);
- double x,y;
- x=m_X; y=m_Y;
- m_X=x*cosa+y*sina;
- m_Y=y*cosa-x*sina;
- }
- //---------------------------------------------------------------------------
- int CFloatPoint::DetectNumChetvertByPoint(CFloatPoint p)
- {
- if (p.m_X<m_X)
- {
- if (p.m_Y>m_Y) return 2;
- else return 3;
- }
- else
- {
- if (p.m_Y>m_Y) return 1;
- else return 4;
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPoint::Minus(double x,double y)
- {
- m_X-=x;
- m_Y-=y;
- }
- //---------------------------------------------------------------------------
- void CFloatPoint::ChangeValuesKoef(double kx,double ky,int typek,bool mult)
- {
- if (kx==0 && ky==0) return;
- if (mult)
- {
- if (typek==0)
- {
- m_X=m_X*(1+kx);
- m_Y=m_Y*(1+ky);
- }
- else if (typek==1)
- {
- m_X=m_X/(1-kx);
- m_Y=m_Y/(1-ky);
- }
- }
- else
- {
- if (typek==0)
- {
- m_X=m_X/(1+kx);
- m_Y=m_Y/(1+ky);
- }
- else if (typek==1)
- {
- m_X=m_X*(1-kx);
- m_Y=m_Y*(1-ky);
- }
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPoint::ChangeEdinIzm(double k)
- {
- if (m_X!=MyDBL_MAX) m_X=RoundTo(m_X*k,-1);
- if (m_Y!=MyDBL_MAX) m_Y=RoundTo(m_Y*k,-1);
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::ChangeEdinIzm(double k)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- Get(i)->ChangeEdinIzm(k);
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::ChangeEdinIzm(int curtype,int type)
- {
- // double k=GetKoefEdinIzm(curtype,type);
- // ChangeEdinIzm(k);
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::Append(CFloatPointArray *parray)
- {
- int i,q=parray->GetCount();
- CFloatPoint *p;
- for (i=0;i<q;i++)
- {
- p=parray->Get(i);
- if (GetByXY(p->m_X,p->m_Y)==NULL) Append(p);
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::CopyAll(CFloatPointArray *parray)
- {
- int i,q=parray->GetCount();
- CFloatPoint *p,*fp;
- for (i=0;i<q;i++)
- {
- p=parray->Get(i);
- fp=new CFloatPoint(p);
- Add(fp);
- }
- }
- //---------------------------------------------------------------------------
- int CFloatPointArray::Insert(int ind,CFloatPoint *p)
- {
- if (ind>0) {CObectArray::Insert(ind,p); return ind;}
- else { Append(p); return GetCount()-1;}
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetByXY(double x,double y)
- {
- int i,q=GetCount();
- CFloatPoint *p;
- x=RoundTo(x,-2); y=RoundTo(y,-2);
- double px,py;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- px=RoundTo(p->m_X,-2); py=RoundTo(p->m_Y,-2);
- if (px==x && py==y) return p;
- }
- return NULL;
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetByName(AnsiString name)
- {
- int i,q=GetCount();
- CFloatPoint *p;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- if (p->m_Name==name) return p;
- }
- return NULL;
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetNext(int ind)
- {
- int q=GetCount(),i=ind+1;
- if (i<q) return Get(i);
- else return Get(0);
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetPrev(int ind)
- {
- int q=GetCount()-1,i=ind-1;
- if (i<0) return Get(q);
- else return Get(i);
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetNext(CFloatPoint *p)
- {
- int ind=IndexByPoint(p);
- return GetNext(ind);
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetPrev(CFloatPoint *p)
- {
- int ind=IndexByPoint(p);
- return GetPrev(ind);
- }
- //---------------------------------------------------------------------------
- int CFloatPointArray::IndexByName(AnsiString name)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- if (Get(i)->m_Name==name) return i;
- return -1;
- }
- //---------------------------------------------------------------------------
- int CFloatPointArray::IndexByPoint(CFloatPoint *p)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- if (Get(i)==p) return i;
- return -1;
- }
- //---------------------------------------------------------------------------
- bool CFloatPointArray::PointInLine(double x,double y,CFloatPoint *fp1,CFloatPoint *fp2)
- {
- /*double d,px,py;
- //высчитываем дельту...
- double Drob=sqrt((fp2->m_X-fp1->m_X)*(fp2->m_X-fp1->m_X)+(fp2->m_Y2-m_Y1)*(m_Y2-m_Y1));
- if (Drob==0) return false;
- d=fabs(((m_Y1-m_Y2)*x+(m_X2-m_X1)*y+(m_X1*m_Y2-m_X2*m_Y1))/Drob);
- if (d<=RECTSIZE*2)
- {
- double a1,b1,c1,a2,b2,c2;
- a1=m_Y1-m_Y2;
- b1=m_X2-m_X1;
- c1=-(m_X1*a1+m_Y1*b1);
- a2=b1;
- b2=-a1;
- c2=-(a2*x+b2*y);
- if (a1==0.)
- {
- py=-c1/b1;
- px=(-c2-b2*py)/a2;
- }
- else if (b1==0.)
- {
- px=-c1/a1;
- py=(-c2-a2*px)/b2;
- }
- else
- {
- py=(a2*c1-a1*c2)/(a1*b2-a2*b1);
- px=(-b1*py-c1)/a1;
- }
- //проверяем принадлежит ли точка отрезку, через сумму длин...
- double len1=ECCore::CalcLengthLine(px,py,m_X1,m_Y1),
- len2=ECCore::CalcLengthLine(px,py,m_X2,m_Y2),
- len =ECCore::CalcLengthLine(m_X1,m_Y1,m_X2,m_Y2);
- double tmp1=RoundTo((len1+len2),-1),tmp2=RoundTo(len,-1);
- if (tmp1>tmp2) return false;
- return true;
- }
- return false; */
- }
- //---------------------------------------------------------------------------
- bool CFloatPointArray::CheckedLine(double x1,double y1,double x2,double y2)
- {
- int i,q=GetCount();
- CFloatPoint *fp1,*fp2;
- double tmp1,tmp2,tmp3,tmp4;
- double tmp5,tmp6,tmp7,tmp8;
- tmp5=ECCore::RoundToCalc(x1,-2); tmp6=ECCore::RoundToCalc(y1,-2);
- tmp7=ECCore::RoundToCalc(x2,-2); tmp8=ECCore::RoundToCalc(y2,-2);
- for (i=0;i<q;i++)
- {
- fp1=Get(i);
- fp2=GetNext(i);
- tmp1=ECCore::RoundToCalc(fp1->m_X,-2); tmp2=ECCore::RoundToCalc(fp1->m_Y,-2);
- tmp3=ECCore::RoundToCalc(fp2->m_X,-2); tmp4=ECCore::RoundToCalc(fp2->m_Y,-2);
- if (((CompareValue(tmp1,tmp5)==0 && CompareValue(tmp2,tmp6)==0) &&
- (CompareValue(tmp3,tmp7)==0 && CompareValue(tmp4,tmp8)==0)) ||
- ((CompareValue(tmp1,tmp7)==0 && CompareValue(tmp2,tmp8)==0) &&
- (CompareValue(tmp3,tmp5)==0 && CompareValue(tmp4,tmp6)==0)))
- return true;
- }
- return false;
- }
- //---------------------------------------------------------------------------
- double CFloatPointArray::CheckedLineForMFShov(double x1, double y1, double x2, double y2)
- {
- double len=0,angle,delta,ll;
- CFloatPoint *p1=new CFloatPoint(),
- *p2=new CFloatPoint(),*pp1,*pp2;
- CFloatPoint fp1,fp2;
- fp1.m_X=x1; fp1.m_Y=y1;
- fp2.m_X=x2; fp2.m_Y=y2;
- fp1.m_X=0; fp1.m_Y=0;
- fp2.Minus(x1,y1);
- angle=ECCore::DetectAngle(fp1.m_X,fp1.m_Y,fp2.m_X,fp2.m_Y,fp2.m_X,fp1.m_Y);
- int chet=ECCore::DetectChetvertPoint(fp2.m_X,fp2.m_Y);
- if (chet==2) angle=180-angle;
- else if (chet==3) angle=180+angle;
- else if (chet==4) angle=360-angle;
- fp2.RotatePoint(angle);
- Minus(x1,y1);
- RotateAllPoint(angle);
- //функция для подсчета пользовательских швов...
- len=ECCore::CalcLengthLine(fp1.m_X,fp1.m_Y,fp2.m_X,fp2.m_Y);
- int i,q=Count-1;
- for (i=0;i<q;i+=2)
- {
- pp1=Get(i);
- pp2=Get(i+1);
- delta=fabs(pp1->m_Y-pp2->m_Y);
- if (delta>3) continue;//если прямая не параллельна оси ОХ
- if (pp1->m_X>pp2->m_X) { p1->m_X=pp2->m_X; p2->m_X=pp1->m_X; }
- else { p1->m_X=pp1->m_X; p2->m_X=pp2->m_X; }
- p1->m_Y=pp1->m_Y; p2->m_Y=pp2->m_Y;
- delta=fabs(p1->m_Y-fp1.m_Y);
- if (delta>3) continue;//3сантиметра погрешность
- //идем проверять все случаии, а их 8 штук, строго слева на право!!
- //fp1*----------*fp2
- // p1*--------------*p2
- if (fp1.m_X<p1->m_X && fp2.m_X<p1->m_X) ll=0;
- // fp1*----------*fp2
- //p1*--------------*p2
- else if (fp1.m_X>p1->m_X && fp1.m_X>p2->m_X) ll=0;
- //fp1*-----------------*fp2
- // p1*----------------*p2
- else if (fp1.m_X<=p1->m_X && fp2.m_X>p1->m_X && fp2.m_X<=p2->m_X)
- ll=ECCore::CalcLengthLine(p1->m_X,p1->m_Y,fp2.m_X,fp2.m_Y);
- // fp1*-----------------*fp2
- // p1*-----------------*p2
- else if (fp1.m_X>=p1->m_X && fp1.m_X<p2->m_X && fp2.m_X>=p2->m_X)
- ll=ECCore::CalcLengthLine(fp1.m_X,fp1.m_Y,p2->m_X,p2->m_Y);
- // fp1*-----------------*fp2
- // p1*--------------------------------*p2
- else if (fp1.m_X>=p1->m_X && fp1.m_X<p2->m_X && fp2.m_X<=p2->m_X)
- ll=ECCore::CalcLengthLine(fp1.m_X,fp1.m_Y,fp2.m_X,fp2.m_Y);
- //fp1*-------------------------*fp2
- // p1*------------*p2
- else if (fp1.m_X<=p1->m_X && fp2.m_X>=p2->m_X)
- ll=ECCore::CalcLengthLine(p1->m_X,p1->m_Y,p2->m_X,p2->m_Y);
- else ll=0;
- len-=ll;
- }
- RotateAllPoint(-angle);
- Minus(-x1,-y1);
- if (len<0) len=0;
- return len;
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::GetGPCPolygon(gpc_polygon *polygon)
- {
- CFloatPoint *p;
- int i,ind,q=GetCount(),countpolygon;
- countpolygon=1;
- int *cPoints=new int[q];
- cPoints[0]=q;
- ind=0;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- if (p->m_BeginVirez)
- {
- cPoints[countpolygon-1]=ind;
- countpolygon++;
- ind=0;
- }
- ind++;
- }
- if (countpolygon>1) cPoints[countpolygon-1]=ind;
- polygon->num_contours=countpolygon;
- polygon->contour=new gpc_vertex_list[countpolygon];
- ind=0;
- polygon->contour[ind].num_vertices=cPoints[ind];
- polygon->contour[ind].vertex=new gpc_vertex[cPoints[ind]];
- int ii=0;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- if (p->m_BeginVirez)
- {
- ind++;
- polygon->contour[ind].num_vertices=cPoints[ind];
- polygon->contour[ind].vertex=new gpc_vertex[cPoints[ind]];
- ii=0;
- }
- polygon->contour[ind].vertex[ii].x=p->m_X;
- polygon->contour[ind].vertex[ii].y=p->m_Y;
- ii++;
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::ConvertGPCPolygon(gpc_polygon polygon)
- {
- int i,j,q,qp=polygon.num_contours;
- CFloatPointArray *array;
- CFloatPoint *fp;
- for (i=0;i<qp;i++)
- {
- fp=new CFloatPoint();
- if (i!=0) fp->m_BeginVirez=true;
- q=polygon.contour[i].num_vertices;
- for (j=0;j<q;j++)
- {
- fp->m_X=polygon.contour[i].vertex[j].x;
- fp->m_Y=polygon.contour[i].vertex[j].y;
- Append(fp);
- fp->m_BeginVirez=false;
- // array->Append(polygon.contour[i].vertex[j].x,polygon.contour[i].vertex[j].y,"",false);//не проверять на одинаковые точки...
- }
- }
- }
- //---------------------------------------------------------------------------
- //---------------------------------------------------------------------------
- bool CFloatPointArray::RotateAllPoint(double angle,bool radian)
- {
- if (angle==0) return false;
- int i,q=GetCount();
- CFloatPoint *p;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- p->RotatePoint(angle,radian);
- }
- return true;
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::Swap(int ind1,int ind2)
- {
- int q=GetCount();
- if (ind1>q || ind2>q || ind1==ind2) return;
- CFloatPoint *p1=Get(ind1),*p2=Get(ind2);
- /*CFloatPoint tp(p1->m_X,p1->m_Y);
- tp.m_Name=p1->m_Name;
- tp.m_BeginVirez=p1->m_BeginVirez;
- */
- CFloatPoint tp=*p1;
- p1->m_X=p2->m_X;
- p1->m_Y=p2->m_Y;
- p1->m_Name=p2->m_Name;
- p1->m_BeginVirez=p2->m_BeginVirez;
- p2->m_X=tp.m_X;
- p2->m_Y=tp.m_Y;
- p2->m_Name=tp.m_Name;
- p2->m_BeginVirez=tp.m_BeginVirez;
- }
- //---------------------------------------------------------------------------
- int CFloatPointArray::Move(int cur,int npos)
- {
- int i;
- if (cur>npos)
- {
- for (i=cur;i>npos;i--) Swap(i,(i-1));
- return (npos-1);
- }
- else
- {
- for (i=cur;i<npos;i++) Swap(i,(i+1));
- return (npos+1);
- }
- }
- //---------------------------------------------------------------------------
- bool CFloatPointArray::PointInPolygon(double x,double y)
- {
- int i,q=GetCount();
- if (q<3) return false;
- double xnew,ynew;
- double xold,yold;
- double x1,y1;
- double x2,y2;
- bool inside=false;
- CFloatPoint *fp=Get(q-1);
- xold=fp->m_X;
- yold=fp->m_Y;
- for (i=0;i<q;i++)
- {
- fp=Get(i);
- xnew=fp->m_X;
- ynew=fp->m_Y;
- if (xnew > xold)
- {
- x1=xold; x2=xnew;
- y1=yold; y2=ynew;
- }
- else
- {
- x1=xnew; x2=xold;
- y1=ynew; y2=yold;
- }
- if ((xnew < x) == (x <= xold) /* edge "open" at left end */
- && (y-y1)*(x2-x1)
- < (y2-y1)*(x-x1))
- {
- inside=!inside;
- }
- xold=xnew;
- yold=ynew;
- }
- return inside;
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::DeletePointNotPolotno(double shov1,double shov2)
- {
- int i,q=GetCount();
- CFloatPoint *p;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- if (shov1<=p->m_Y && p->m_Y<=shov2) continue;
- Remove(i); q--; i--;
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::SortByX()
- {
- int i,q=GetCount()-1;
- CFloatPoint *f1,*f2;
- double tmp1,tmp2;
- for (i=0;i<q;i++)
- {
- f1=Get(i); f2=Get(i+1);
- tmp1=RoundTo(f1->m_X,0); tmp2=RoundTo(f2->m_X,0);
- if (tmp1>tmp2)
- {
- Swap(i,i+1);
- i=-1;
- }
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::SortByYAndX()
- {
- int i,j,q=GetCount()-1;
- CFloatPoint *p1,*p2;
- //сортируем по Y (группируя по линиям)
- for (i=0;i<q;i++)
- {
- p1=Get(i); p2=Get(i+1);
- //if (p1->m_Y>p2->m_Y) {Move(i,i+1); i=-1;}
- if (p1->m_Y<p2->m_Y) {Swap(i,i+1); i=-1;}
- }
- //
- double tmp1,tmp2;
- for (i=0;i<q;i++)
- {
- p1=Get(i); p2=Get(i+1);
- tmp1=RoundTo(p1->m_Y,-4); tmp2=RoundTo(p2->m_Y,-4);
- if (tmp1!=tmp2) continue;
- if (p1->m_X>p2->m_X) {Swap(i,i+1); i=-1;}
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::SortByXHight()
- {
- int i,j,q=GetCount()-1;
- CFloatPoint *p1,*p2;
- //сортируем по X
- for (i=0;i<q;i++)
- {
- p1=Get(i); p2=Get(i+1);
- //if (p1->m_Y>p2->m_Y) {Move(i,i+1); i=-1;}
- if (p1->m_X>p2->m_X) {Swap(i,i+1); i=-1;}
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::SortNameInPoints()
- {
- int i,j,q=GetCount()-1;
- CFloatPoint *p1,*p2;
- AnsiString tp;
- //сортируем по Y (группируя по линиям)
- for (i=0;i<q;i++)
- {
- p1=Get(i); p2=Get(i+1);
- if (p1->m_Name=="" || p2->m_Name=="") continue;
- if (p1->m_Name>p2->m_Name)
- {
- tp=p1->m_Name;
- p1->m_Name=p2->m_Name;
- p2->m_Name=tp;
- i=-1;
- }
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::SortByName()
- {
- int i,q=GetCount()-1;
- CFloatPoint *f1,*f2;
- for (i=0;i<q;i++)
- {
- f1=Get(i); f2=Get(i+1);
- if (f1->m_Name>f2->m_Name)
- {
- Swap(i,i+1);
- i=-1;
- }
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::ChangeBaseAngle(int PosXY)
- {
- CFloatPoint Min,Max,*point;
- double tdx,tdy;
- GetMinMaxXY(Min,Max);
- int i,q=GetCount();
- for (i=0;i<q;i++)
- {
- point=Get(i);
- if (PosXY==2 || PosXY==3) { tdx=Max.m_X-point->m_X; point->m_X=tdx;}
- if (PosXY==1 || PosXY==3) { tdy=Max.m_Y-point->m_Y; point->m_Y=tdy;}
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::DeleteDuplicate()
- {
- //изменил в версии 1.35
- /*int i,j,q=GetCount();
- CFloatPoint *p1,*p2;
- for (i=0;i<q;i++)
- {
- p1=Get(i);
- for (j=i+1;j<q;j++)
- {
- if (i==j) continue;
- p2=Get(j);
- if (p1->m_Name!="" && p1->m_Name==p2->m_Name)
- {
- Remove(j);
- i--; q--;
- break;
- }
- }
- }*/
- int i,j,q=GetCount();
- CFloatPoint *p1,*p2;
- for (i=0;i<q;i++)
- {
- p1=Get(i);
- p2=GetNext(i);
- if (p1->m_Name!="" && p1->m_Name==p2->m_Name)
- {
- Remove(i);
- i--; q--;
- }
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::GetMinMaxXY(CFloatPoint &Min,CFloatPoint &Max)
- {
- int i,q=GetCount();
- Min.m_X=Min.m_Y=Max.m_X=Max.m_Y=MyDBL_MAX;
- CFloatPoint *p;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- if (Min.m_X==MyDBL_MAX || p->m_X<Min.m_X) Min.m_X=p->m_X;
- if (Min.m_Y==MyDBL_MAX || p->m_Y<Min.m_Y) Min.m_Y=p->m_Y;
- if (Max.m_X==MyDBL_MAX || p->m_X>Max.m_X) Max.m_X=p->m_X;
- if (Max.m_Y==MyDBL_MAX || p->m_Y>Max.m_Y) Max.m_Y=p->m_Y;
- }
- }
- //---------------------------------------------------------------------------
- UnicodeString CFloatPointArray::LoadFromString(UnicodeString str)
- {
- int pos=0,q=str.Length();
- UnicodeString res;
- int i,qq,v;
- CFloatPoint *fp;
- pos=str.Pos(";");
- qq=StrToInt(str.SubString(1,pos-1));
- str=str.SubString(pos+1,q-pos);
- for (i=0;i<qq;i++)
- {
- fp=new CFloatPoint();
- pos=str.Pos(";");
- fp->m_Name=str.SubString(1,pos-1);
- str=str.SubString(pos+1,q-pos);
- pos=str.Pos(";");
- fp->m_X=ECCore::MyStrToFloat(str.SubString(1,pos-1));
- str=str.SubString(pos+1,q-pos);
- pos=str.Pos(";");
- fp->m_Y=ECCore::MyStrToFloat(str.SubString(1,pos-1));
- str=str.SubString(pos+1,q-pos);
- pos=str.Pos(";");
- v=StrToInt(str.SubString(1,pos-1));
- str=str.SubString(pos+1,q-pos);
- if (v==0) fp->m_BeginVirez=false;
- else fp->m_BeginVirez=true;
- Add(fp);
- }
- return str;
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::SaveToDXF(UnicodeString FileName)
- {
- // PolygonsArray polygonArray;
- // MyPolygon *polygon=new MyPolygon();
- // Vertex2D vertex;
- // int i,q=Count;
- // CFloatPoint *curpoint;
- // for (i=0;i<q;i++)
- // {
- // curpoint=Get(i);
- // if (curpoint->m_BeginVirez)
- // {
- // polygon->closed = true;
- // polygonArray.push_back(*polygon);
- // polygon=new MyPolygon();
- // }
- // vertex.x = curpoint->m_X; vertex.y = curpoint->m_Y;
- // polygon->vertices.push_back(vertex);
- // }
- // polygon->closed = true;
- // polygonArray.push_back(*polygon);
- //
- // AnsiString file=FileName;
- // CFloatPoint min,max;
- // GetMinMaxXY(min,max);
- // bool result = writePolygonDXF(file.c_str(), polygonArray,min.m_X,min.m_Y,max.m_X,max.m_Y);
- /*#define DXF_HEADER "0\r\nSECTION\r\n2\r\nENTITIES\r\n"
- #define DXF_LINEHEADER "0\r\LINE\r\n10\r\n%.06f\r\n20\r\n%.06f\r\n"
- #define DXF_LINEFOOTER "11\r\n%.06f\r\n21\r\n%.06f\r\n"
- #define DXF_FOOTER "0\r\nENDSEC"*/
- /*HANDLE hFile;
- if((hFile = CreateFileW(FileName.w_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) != INVALID_HANDLE_VALUE)
- {
- DWORD dwWritten;
- WriteFile(hFile, DXF_HEADER, lstrlen(DXF_HEADER), &dwWritten, NULL);
- CFloatPoint *firstpoint = Get(0);
- CHAR * buf = new CHAR[256];
- CFloatPoint *curpoint;
- CFloatPoint *prevpoint;
- int i,q=Count;
- for (i = 1; i <= q; i++)
- {
- if (i == Count)
- {
- curpoint = (CFloatPoint *)Get(i-1);
- prevpoint = firstpoint;
- }
- else
- {
- curpoint = (CFloatPoint *)Get(i);
- if(curpoint->m_BeginVirez)
- {
- curpoint = (CFloatPoint *)Get(i-1);
- prevpoint = firstpoint;
- }
- else
- prevpoint = (CFloatPoint *)Get(i-1);
- if(prevpoint->m_BeginVirez)
- {
- firstpoint = prevpoint;
- }
- }
- sprintf((CHAR *)&buf[0], DXF_LINEHEADER, curpoint->m_X, curpoint->m_Y);
- WriteFile(hFile, buf, lstrlen((CHAR *)&buf[0]), &dwWritten, NULL);
- sprintf((CHAR *)&buf[0], DXF_LINEFOOTER, prevpoint->m_X, prevpoint->m_Y);
- WriteFile(hFile, buf, lstrlen((CHAR *)&buf[0]), &dwWritten, NULL);
- }
- WriteFile(hFile, DXF_FOOTER, lstrlen(DXF_FOOTER), &dwWritten, NULL);
- delete[] buf;
- }
- CloseHandle(hFile); */
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::Minus(double x,double y)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- Get(i)->Minus(x,y);
- }
- //---------------------------------------------------------------------------
- void CFloatPointArray::Invert()
- {
- int i,q=GetCount();
- CFloatPoint *p;
- for (i=0;i<q;i++)
- {
- p=Get(i);
- p->m_X*=-1;
- }
- }
- //---------------------------------------------------------------------------
- UnicodeString CFloatPointArray::SaveToStr()
- {
- UnicodeString str;
- int i,q=GetCount();
- CFloatPoint *fp;
- str=q; str+=";";
- for (i=0;i<q;i++)
- {
- fp=Get(i);
- str+=fp->m_Name; str+=";";
- str+=fp->m_X; str+=";";
- str+=fp->m_Y; str+=";";
- if (fp->m_BeginVirez) str+="1;";
- else str+="0;";
- }
- return str;
- }
- //---------------------------------------------------------------------------
- double CFloatPointArray::CalcPlochad(bool virez)
- {
- int i,q=GetCount(),qp=q;
- if (virez)
- {
- for (i=0;i<q;i++)
- if (Get(i)->m_BeginVirez) {qp=i; break;}
- }
- double s,sresv=0,resv=0,res=0,sd;
- // Расчет площади многоугольника через сумму площадей трапеций
- for (i = 0; i < qp; i++)
- {
- if (i == 0)
- {
- s = Get(i)->m_X*(Get(qp-1)->m_Y - Get(i+1)->m_Y); //если i == 0, то y[i-1] заменяем на y[n-1]
- res += s;
- }
- else if (i == qp-1)
- {
- s = Get(i)->m_X*(Get(i-1)->m_Y - Get(0)->m_Y); // если i == n-1, то y[i+1] заменяем на y[0]
- res += s;
- }
- else
- {
- s = Get(i)->m_X*(Get(i-1)->m_Y - Get(i+1)->m_Y);
- res += s;
- }
- }
- sd = fabs(res/2);
- //внутренний вырез
- if (virez)
- {
- int ib=qp;
- for (i = qp; i < q; i++)
- {
- if (i == ib)
- {
- s = Get(i)->m_X*(Get(q-1)->m_Y - Get(i+1)->m_Y); //если i == 0, то y[i-1] заменяем на y[n-1]
- resv += s;
- }
- else if ((i == q-1) || Get(i+1)->m_BeginVirez)
- {
- s = Get(i)->m_X*(Get(i-1)->m_Y - Get(ib)->m_Y); // если i == n-1, то y[i+1] заменяем на y[0]
- resv += s;
- ib=i+1; sresv+=fabs(resv/2); resv=0;
- }
- else
- {
- s = Get(i)->m_X*(Get(i-1)->m_Y - Get(i+1)->m_Y);
- resv += s;
- }
- }
- sd-=sresv;
- }
- return sd;
- }
- //---------------------------------------------------------------------------
- double CFloatPointArray::SideLength(double x1,double y1,double x2,double y2)
- {
- double a = sqrt((x2-x1)/10*(x2-x1)/10+(y2-y1)/10*(y2-y1)/10);
- return a*10;
- }
- //---------------------------------------------------------------------------
- int CFloatPointArray::GetPointByCircle(double x1,double y1,double r1,double x2,double y2,double r2,
- double &rx1,double &ry1,double &rx2,double &ry2)
- {
- const double EPS = 0.000001;
- x2-=x1; y2-=y1;
- //
- double a=-2*x2, b=-2*y2, c=x2*x2+y2*y2+r1*r1-r2*r2,ab;
- if ((a*a+b*b)==0.) return 0;
- double x0 = -a*c/(a*a+b*b), y0 = -b*c/(a*a+b*b),tmp;
- double res1=c*c,
- res2=r1*r1*(a*a+b*b);
- //if (c*c>(r1*r1*(a*a+b*b)+EPS)) return ccNone;
- //else if (fabs(c*c-r1*r1*(a*a+b*b))<EPS)
- if (CompareValue(res1,res2+EPS)>0) return 0;
- else if (CompareValue(fabs(res1-res2),EPS)<0)
- {
- rx1=x1+x0;
- ry1=y1+y0;
- return 1;
- }
- else
- {
- double d = r1*r1 - c*c*1.0/(a*a+b*b);
- double mult; //double mult = sqrt (d / (a*a+b*b));
- if (d<=0.) mult=0;
- else mult = sqrt (d / (a*a+b*b));
- double ax,ay,bx,by;
- ax = x0 + b * mult;
- bx = x0 - b * mult;
- ay = y0 - a * mult;
- by = y0 + a * mult;
- rx1=x1+ax; ry1=y1+ay;
- rx2=x1+bx; ry2=y1+by;
- return 2;
- }
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetCrossPointTwoLine(CFloatPoint p1,CFloatPoint p2,CFloatPoint P1,CFloatPoint P2)
- {
- //проверяем на наличее общей точки...
- if ((CompareValue(p1.m_X,P1.m_X,0.0001)==0 && CompareValue(p1.m_Y,P1.m_Y,0.0001)==0) ||
- (CompareValue(p1.m_X,P2.m_X,0.0001)==0 && CompareValue(p1.m_Y,P2.m_Y,0.0001)==0))
- return new CFloatPoint(p1.m_X,p1.m_Y);
- else if ((CompareValue(p2.m_X,P2.m_X,0.0001)==0 && CompareValue(p2.m_Y,P2.m_Y,0.0001)==0) ||
- (CompareValue(p2.m_X,P1.m_X,0.0001)==0 && CompareValue(p2.m_Y,P1.m_Y,0.0001)==0))
- return new CFloatPoint(p2.m_X,p2.m_Y);
- //
- CFloatPoint b,d,c,dd,I;
- b.m_X=p2.m_X-p1.m_X;
- b.m_Y=p2.m_Y-p1.m_Y;
- d.m_X=P2.m_X-P1.m_X;
- d.m_Y=P2.m_Y-P1.m_Y;
- c.m_X=P1.m_X-p1.m_X;
- c.m_Y=P1.m_Y-p1.m_Y;
- dd.m_X=-d.m_Y;
- dd.m_Y= d.m_X;
- double ddxc,ddxb,t;
- ddxc=dd.m_X*c.m_X+dd.m_Y*c.m_Y;
- ddxb=dd.m_X*b.m_X+dd.m_Y*b.m_Y;
- if (ddxb==0) return NULL;//отрезки паралельны...
- t=ddxc/ddxb;
- I.m_X=p1.m_X+t*b.m_X;
- I.m_Y=p1.m_Y+t*b.m_Y;
- double x,y;
- x=RoundTo(I.m_X,-4); y=RoundTo(I.m_Y,-4);
- //проверяем является ли эти две отрезка одно прямой...
- //double maxX,minX,maxY,minY;
- //if (p2.m_X>P2.m_X) maxX=p2.m_X
- return new CFloatPoint(x,y);
- }
- //---------------------------------------------------------------------------
- CFloatPointArray *CFloatPointArray::GetCrossPoint(CFloatPoint P1,CFloatPoint P2,bool line2point,bool NotPointLine,bool TwinsPoint,bool Epsilon)
- {
- //TwinsPoint - избегать такого же отрезока
- CFloatPointArray *PointArray=new CFloatPointArray();
- CFloatPoint *p1,*p2;
- CFloatPoint *newp,*tp;
- //перебераем точки в основной схеме...
- int i,i2,q=GetCount();
- AnsiString s;
- double t1,t2,t3,t4;
- for (i=0;i<q;i++)
- {
- p1=Get(i);
- i2=i+1;
- if (i2==q) p2=Get(0);
- else p2=Get(i2);
- if (TwinsPoint)
- {
- if (CompareValue(p1->m_X,P1.m_X)==0 && CompareValue(p1->m_Y,P1.m_Y)==0 &&
- CompareValue(p2->m_X,P2.m_X)==0 && CompareValue(p2->m_Y,P2.m_Y)==0) continue;
- }
- newp=GetCrossPoint(p1,p2,P1,P2,line2point,NotPointLine);
- if (newp==NULL) continue;
- else if (TwinsPoint)
- {
- t1=RoundTo(p1->m_X,-4); t2=RoundTo(p1->m_Y,-4);
- t3=RoundTo(p2->m_X,-4); t4=RoundTo(p2->m_Y,-4);
- if ((CompareValue(t1,newp->m_X)==0 && CompareValue(t2,newp->m_Y)==0) ||
- (CompareValue(t3,newp->m_X)==0 && CompareValue(t4,newp->m_Y)==0)) continue;
- }
- if (Epsilon)
- {
- t1=fabs(fabs(p1->m_X-p2->m_X)-fabs(P1.m_X-P2.m_X));
- t2=fabs(fabs(p1->m_Y-p2->m_Y)-fabs(P1.m_Y-P2.m_Y));
- if (CompareValue(t1,5.)<=0 || CompareValue(t2,5.)<=0) continue;//2 это сантиметры, допустимое окно для пересечения на случай мнимого разреза...
- }
- s=p1->m_Name; s+=p2->m_Name;
- newp->m_Name=s;
- PointArray->Append(newp);
- }
- return PointArray;
- }
- //---------------------------------------------------------------------------
- CFloatPoint *CFloatPointArray::GetCrossPoint(CFloatPoint *p1,CFloatPoint *p2,CFloatPoint P1,CFloatPoint P2,bool line2point,bool NotPointLine)
- {
- try
- {
- CFloatPoint b,d,c,dd,I;
- b.m_X=p2->m_X-p1->m_X;
- b.m_Y=p2->m_Y-p1->m_Y;
- if (CompareValue(p2->m_X,p1->m_X)==0) b.m_X=0.;
- if (CompareValue(p2->m_Y,p1->m_Y)==0) b.m_Y=0.;
- d.m_X=P2.m_X-P1.m_X;
- d.m_Y=P2.m_Y-P1.m_Y;
- c.m_X=P1.m_X-p1->m_X;
- c.m_Y=P1.m_Y-p1->m_Y;
- dd.m_X=-d.m_Y;
- dd.m_Y= d.m_X;
- double ddxc,ddxb,t;
- ddxc=dd.m_X*c.m_X+dd.m_Y*c.m_Y;
- ddxb=dd.m_X*b.m_X+dd.m_Y*b.m_Y;
- //if (CompareValue(ddxb,0.)==0) return NULL;//отрезки паралельны...
- if (RoundTo(ddxb,-4)==0.) return NULL;//отрезки паралельны...
- if (ddxb==DBL_MAX) return NULL;//отрезки паралельны...
- t=ddxc/ddxb;
- //if (t>1 || t<0) return NULL;
- I.m_X=p1->m_X+t*b.m_X;
- I.m_Y=p1->m_Y+t*b.m_Y;
- //проверка на пренадлежность точек отрезкам...
- //формируем правельную область пряпоугольников...
- double x,y,xA,xB,yA,yB,xC,xD,yC,yD;
- xA=RoundTo(p1->m_X,-4); yA=RoundTo(p1->m_Y,-4);
- xB=RoundTo(p2->m_X,-4); yB=RoundTo(p2->m_Y,-4);
- //
- xC=RoundTo(P1.m_X,-4); yC=RoundTo(P1.m_Y,-4);
- xD=RoundTo(P2.m_X,-4); yD=RoundTo(P2.m_Y,-4);
- x=RoundTo(I.m_X,-4);
- y=RoundTo(I.m_Y,-4);
- if (xA>xB) {t=xB; xB=xA; xA=t;}
- if (yA>yB) {t=yB; yB=yA; yA=t;}
- if (xC>xD) {t=xD; xD=xC; xC=t;}
- if (yC>yD) {t=yD; yD=yC; yC=t;}
- bool yes=false;
- //if ((xA<=x && x<=xB)&&(yA<=y && y<=yB))
- if ((CompareValue(xA,x)<=0 && CompareValue(x,xB)<=0)&&
- (CompareValue(yA,y)<=0 && CompareValue(y,yB)<=0))
- {
- //проверка на пренодлежность найденой точки ОТРЕЗКУ!!!
- if (line2point)
- {
- //if ((xC<=x && x<=xD)&&(yC<=y && y<=yD)) yes=true;
- if ((CompareValue(xC,x)<=0 && CompareValue(x,xD)<=0)&&
- (CompareValue(yC,y)<=0 && CompareValue(y,yD)<=0)) yes=true;
- else yes=false;
- }
- else yes=true;
- //проверка является ли найденая точка одной из точккой концов отреков...
- if (NotPointLine)
- {
- /*if ((CompareValue(xC,x)==0 && CompareValue(yC,y)==0) ||
- (CompareValue(x,xD)==0 && CompareValue(y,yD)==0) ||
- (CompareValue(xA,x)==0 && CompareValue(yA,y)==0) ||
- (CompareValue(x,xB)==0 && CompareValue(y,yB)==0)) yes=false;*/
- double tx=RoundTo(p1->m_X,-4),ty=RoundTo(p1->m_Y,-4);
- if (CompareValue(tx,x)==0 && CompareValue(ty,y)==0) yes=false;
- tx=RoundTo(p2->m_X,-4),ty=RoundTo(p2->m_Y,-4);
- if (CompareValue(tx,x)==0 && CompareValue(ty,y)==0) yes=false;
- tx=RoundTo(P1.m_X,-4),ty=RoundTo(P1.m_Y,-4);
- if (CompareValue(tx,x)==0 && CompareValue(ty,y)==0) yes=false;
- tx=RoundTo(P2.m_X,-4),ty=RoundTo(P2.m_Y,-4);
- if (CompareValue(tx,x)==0 && CompareValue(ty,y)==0) yes=false;
- }
- if (!yes) return NULL;
- CFloatPoint *newP=new CFloatPoint(x,y);
- return newP;
- }
- return NULL;
- }
- catch(...)
- {return NULL;}
- }
- //---------------------------------------------------------------------------
- CFloatPointArrayArray::CFloatPointArrayArray(CFloatPointArrayArray *mass)
- {
- int i,j,q,q1;
- CFloatPointArray *array,*newarray;
- q1=mass->GetCount();
- for (j=0;j<q1;j++)
- {
- array=mass->Get(j);
- q=array->GetCount();
- newarray=new CFloatPointArray();
- for (i=0;i<q;i++)
- newarray->Append(array->Get(i),false);
- newarray->m_GPC=array->m_GPC;
- Append(newarray);
- }
- }
- //---------------------------------------------------------------------------
- bool CFloatPointArrayArray::CheckedLine(double x1,double y1,double x2,double y2)
- {
- int i,q=GetCount();
- CFloatPointArray *array;
- bool res;
- for (i=0;i<q;i++)
- {
- array=Get(i);
- res=array->CheckedLine(x1,y1,x2,y2);
- if (res) return true;
- }
- return false;
- }
- //---------------------------------------------------------------------------
- int CFloatPointArrayArray::GetCountPoints()
- {
- int i,j,q1,q=GetCount(),count=0;
- CFloatPointArray *pol;
- for (i=0;i<q;i++)
- {
- pol=Get(i);
- count+=pol->GetCount();
- }
- return count;
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::Append(CFloatPointArrayArray *array)
- {
- int i,q=array->GetCount();
- for (i=0;i<q;i++)
- Append(array->Get(i));
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::GetMinMaxXY(CFloatPoint &Min,CFloatPoint &Max)
- {
- int i,q=GetCount();
- Min.m_X=Min.m_Y=MyDBL_MAX;
- Max.m_X=Max.m_Y=MyDBL_MAX;
- CFloatPoint tMin,tMax;
- for (i=0;i<q;i++)
- {
- Get(i)->GetMinMaxXY(tMin,tMax);
- if (Min.m_X==MyDBL_MAX || Min.m_X>tMin.m_X) Min.m_X=tMin.m_X;
- if (Min.m_Y==MyDBL_MAX || Min.m_Y>tMin.m_Y) Min.m_Y=tMin.m_Y;
- if (Max.m_X==MyDBL_MAX || Max.m_X<tMax.m_X) Max.m_X=tMax.m_X;
- if (Max.m_Y==MyDBL_MAX || Max.m_Y<tMax.m_Y) Max.m_Y=tMax.m_Y;
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::ChangeValuesKoef(double kx,double ky, int typek,bool mult)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- Get(i)->ChangeValuesKoef(kx,ky,typek,mult);
- }
- //---------------------------------------------------------------------------
- //void CFloatPointArrayArray::ConvertGPCPolygon(gpc_polygon polygon)
- //{
- // int i,j,q,qp=polygon.num_contours;
- // CFloatPointArray *array;
- // for (i=0;i<qp;i++)
- // {
- // array=new CFloatPointArray();
- // q=polygon.contour[i].num_vertices;
- // for (j=0;j<q;j++)
- // {
- // array->Append(polygon.contour[i].vertex[j].x,polygon.contour[i].vertex[j].y,"",false);//не проверять на одинаковые точки...
- // }
- // Append(array);
- // }
- //}
- ////---------------------------------------------------------------------------
- //void CFloatPointArrayArray::GetGPCPolygon(gpc_polygon *polygon)
- //{
- // CFloatPoint *p;
- // CFloatPointArray *parray;
- // int i,j,ind,q=GetCount(),qp;
- // polygon->num_contours=q;
- // polygon->contour=new gpc_vertex_list[q];
- // ind=0;
- // for (i=0;i<q;i++)
- // {
- // parray=Get(i);
- // qp=parray->GetCount();
- // polygon->contour[ind].num_vertices=qp;
- // polygon->contour[ind].vertex=new gpc_vertex[qp];
- // for (j=0;j<qp;j++)
- // {
- // p=parray->Get(j);
- // polygon->contour[ind].vertex[j].x=p->m_X;
- // polygon->contour[ind].vertex[j].y=p->m_Y;
- // }
- // ind++;
- // }
- //}
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::RotateAllPoint(double angle,bool radian)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- Get(i)->RotateAllPoint(angle,radian);
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::SortPointByCentr()
- {
- //сортируем точки в полотнах...
- CFloatPoint Min,Max;
- double ycur;
- int indb,i,j,q,qp,pos;
- CFloatPoint ttp,*fp;
- CFloatPointArray *array;
- q=GetCount();
- double tmp1,tmp2;
- for (i=0;i<q;i++)
- {
- ycur=100000;
- indb=-1;
- array=Get(i);
- array->GetMinMaxXY(Min,Max);
- qp=array->GetCount();
- //находим минимальную точку(самую левую-нижнюю)
- for (j=0;j<qp;j++)
- {
- fp=array->Get(j);
- tmp1=RoundTo(fp->m_X,-1); tmp2=RoundTo(Min.m_X,-1);
- if (tmp1!=tmp2) continue;//Max.m_X потому что мы отражаем полотна (раскрой с лицевой стороны)...
- tmp1=RoundTo(fp->m_Y,-1); tmp2=RoundTo(Min.m_Y,-1);
- if (tmp1==tmp2) {indb=j; ycur=fp->m_Y; break;}
- tmp1=RoundTo(ycur,-1); tmp2=RoundTo(fp->m_Y,-1);
- if (ycur==100000 || tmp1>tmp2) {indb=j; ycur=fp->m_Y;}
- }
- //определяем последнюю точку (до внутреннего выреза)
- pos=qp-1;
- for (j=0;j<qp;j++)
- {
- if (array->Get(j)->m_BeginVirez) {pos=j-1; break;}
- }
- //перемещаем точки...
- for (j=0;j<indb;j++)
- {
- //ttp=*array->Get(0);
- //array->Remove(0);
- fp=array->Get(0);
- if (pos<(qp-1)) array->Insert(pos+1,fp);//просто pos, потому что мы удалили до этого и индекс сместился...
- else array->Append(fp,false);
- array->Remove(0);
- fp=array->Get(pos);
- }
- //сортируем по часовой стрелке...
- //переворачиваем...
- for (j=1;j<pos;j++)
- {
- if (j>=pos) break;
- fp=array->Get(j);
- fp=array->Get(pos);
- array->Swap(j,pos);
- pos--;
- }
- /*for (j=0;j<qp;j++)
- {
- fp=array->Get(j);
- }*/
- }
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::Minus(double x,double y)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- Get(i)->Minus(x,y);
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::Invert()
- {
- int i,q=GetCount();
- for (i=0;i<q;i++) Get(i)->Invert();
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::ChangeEdinIzm(double k)
- {
- int i,q=GetCount();
- for (i=0;i<q;i++)
- Get(i)->ChangeEdinIzm(k);
- }
- //---------------------------------------------------------------------------
- void CFloatPointArrayArray::ChangeEdinIzm(int curtype,int type)
- {
- // double k=GetKoefEdinIzm(curtype,type);
- // ChangeEdinIzm(k);
- }
- //---------------------------------------------------------------------------
- double CFloatPointArrayArray::CalcPlochad()
- {
- CFloatPointArray *array;
- int i,q=Count;
- double sum=0;
- for (i=0;i<q;i++)
- {
- sum+=Get(i)->CalcPlochad();
- }
- return sum;
- }
- //---------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement