基于狄洛尼三角网生成算法的源代码.docx
《基于狄洛尼三角网生成算法的源代码.docx》由会员分享,可在线阅读,更多相关《基于狄洛尼三角网生成算法的源代码.docx(24页珍藏版)》请在冰豆网上搜索。
基于狄洛尼三角网生成算法的源代码
importjava.util.*;
importjava.awt.*;
publicclassMyEdge{
publicstaticintcount=0;
publicintid;
privateintbegin;
privateintend;
privateintuseCount;
publicMyEdge(intbegin,intend)
{
this.id=++count;
this.begin=begin;
this.end=end;
this.useCount=0;
}
publicMyEdge(MyPointbegin,MyPointend)
{
this.id=++count;
this.begin=begin.id;
this.end=end.id;
this.useCount=0;
}
publicintgetUseCount()
{
returnthis.useCount;
}
publicvoidaddUseCount()
{
this.useCount++;
}
/*
*下面这两个方法是得到边的来个顶点
*若集合中没有指定的对象则返回空值
*/
publicMyPointgetBeginPoint(MappointSet)
{
MyPointtemp=pointSet.get(this.begin);
returntemp;
}
publicMyPointgetEndPoint(MappointSet)
{
MyPointtemp=pointSet.get(this.end);
returntemp;
}
/*
*下面是根据两个点的ID,在边集中找寻两点组成的边
*返回的是边对象
*若没找到,则返回空
*/
publicstaticMyEdgegetEdge(intbegin,intend,MapedgeSet)
{
MyEdgetemp=null;
for(inti=1;i<=edgeSet.size();i++)
{
temp=edgeSet.get(i);
if(temp.begin==begin&&temp.end==end)
break;
}
returntemp;
}
/*
*下面是根据两个点对象,在边集中找寻两点组成的边
*返回的是边对象
*若没找到,则返回空
*/
publicstaticMyEdgegetEdge(MyPointbegin,MyPointend,MapedgeSet)
{
MyEdgetemp=null;
for(inti=1;i<=edgeSet.size();i++)
{
temp=edgeSet.get(i);
if(temp.begin==begin.id&&temp.end==end.id)
break;
}
returntemp;
}
publicvoiddraw(Graphicsg,MappointSet)
{
MyPointbegin=pointSet.get(this.begin);
MyPointend=pointSet.get(this.end);
Colorc=g.getColor();
g.setColor(Color.blue);
g.drawLine(begin.x,begin.y,end.x,end.y);
g.setColor(c);
}
/*
*下面这个方法是用来判断点在当前直线的左边还是右边
*当然当前直线是有方向的
*若点在直线的右边,则返回false
*否则返回true
*/
publicbooleanisOnLeft(MyPointp,MappointSet)
{
booleanflag=false;
MyPointbegin=pointSet.get(this.begin);
MyPointend=pointSet.get(this.end);
intLine=(begin.y-end.y)*p.x+(end.x-begin.x)*p.y-end.x*begin.y+end.y*begin.x;
if(Line<0)flag=true;
returnflag;
}
/*
*比较两个边是否相等
*这个方法排除了边的方向性
*只要空间上是一条边
*就是同一条边即相等
*/
publicbooleanequals(Objectedge)
{
booleanflag=false;
if(this.end==((MyEdge)edge).begin&&this.begin==((MyEdge)edge).end||this.begin==((MyEdge)edge).begin&&this.end==((MyEdge)edge).end)flag=true;
returnflag;
}
/*
*下面这个方法是将边的方向翻转
*/
publicvoidturnBeginAndEnd()
{
inttemp=this.begin;
this.begin=this.end;
this.end=temp;
}
/*
*下面这个方法是找到当前边的左边最优点
*采用外接圆的方法
*如果该边有左边最优点则返回之
*否则返回空
*/
publicMyPointfindGoodPointByCircle(MappointSet,MapedgeSet,MaptriangleSet)
{
MyPointgoodPoint=null;
for(inti=1;i<=pointSet.size();i++)
{
MyPointactivePoint=pointSet.get(i);
if(this.isOnLeft(activePoint,pointSet))//判断当前活动点是不是在直线的左边
{//在直线左边
MyTriangleactiveTriangle=newMyTriangle(this.begin,i,this.end);
intgood=i;
for(intj=i+1;j<=pointSet.size();j++)
{//对当前活动边的左边点进行空圆准则检验
if(this.isOnLeft(pointSet.get(j),pointSet))//判断当前活动点是不是在直线的左边
{
if(activeTriangle.isInCircle(pointSet.get(j),pointSet))
{
activeTriangle=newMyTriangle(this.begin,j,this.end);
good=j;
}
}
}
goodPoint=pointSet.get(good);
/*
*下面是生成边后的后期处理
*/
//生成的第一边
MyEdgenewEdge1=newMyEdge(this.getBeginPoint(pointSet),goodPoint);
newEdge1.addUseCount();
if(edgeSet.containsValue(newEdge1))
{
MyEdge.count--;
for(intk=1;k<=edgeSet.size();k++)
{
if(edgeSet.get(k).equals(newEdge1))
{
edgeSet.get(k).addUseCount();
break;
}
}
}else
edgeSet.put(newEdge1.id,newEdge1);
//生成的第二边
MyEdgenewEdge2=newMyEdge(goodPoint,this.getEndPoint(pointSet));
newEdge2.addUseCount();
if(edgeSet.containsValue(newEdge2))
{
MyEdge.count--;
for(intk=1;k<=edgeSet.size();k++)
{
if(edgeSet.get(k).equals(newEdge2))
{
edgeSet.get(k).addUseCount();
break;
}
}
}else
edgeSet.put(newEdge2.id,newEdge2);
//对第三边进行处理
this.addUseCount();
this.turnBeginAndEnd();
//生成三角形,并加入到三角形集合中
MyTrianglenewTriangle=newMyTriangle(this.getBeginPoint(pointSet),goodPoint,this.getEndPoint(pointSet),edgeSet);
triangleSet.put(newTriangle.id,newTriangle);
break;
}
}
returngoodPoint;
}
/*
*下面是另一种找最优点的方法
*基于角度的方法
*用余弦值最小的那个点
*/
publicMyPointfindGoodPointByAngle(MappointSet,MapedgeSet,MaptriangleSet)
{
MyPointgoodPoint=null;
for(inti=1;i<=pointSet.size();i++)
{
MyPointactivePoint=pointSet.get(i);
if(this.isOnLeft(activePoint,pointSet))//判断当前活动点是不是在直线的左边
{//在直线左边
doubleminCos=this.getCos(activePoint,pointSet);
intgood=i;
for(intj=i+1;j<=pointSet.size();j++)
{//对当前活动边的左边点进行空圆准则检验
if(this.isOnLeft(pointSet.get(j),pointSet))//判断当前活动点是不是在直线的左边
{
doublecos=this.getCos(pointSet.get(j),pointSet);
if(cos{
minCos=cos;
good=j;
}
}
}
goodPoint=pointSet.get(good);
/*
*下面是生成边后的后期处理
*/
//生成的第一边
MyEdgenewEdge1=newMyEdge(this.getBeginPoint(pointSet),goodPoint);
newEdge1.addUseCount();
if(edgeSet.containsValue(newEdge1))
{
MyEdge.count--;
for(intk=1;k<=edgeSet.size();k++)
{
if(edgeSet.get(k).equals(newEdge1))
{
edgeSet.get(k).addUseCount();
break;
}
}
}else
edgeSet.put(newEdge1.id,newEdge1);
//生成的第二边
MyEdgenewEdge2=newMyEdge(goodPoint,this.getEndPoint(pointSet));
newEdge2.addUseCount();
if(edgeSet.containsValue(newEdge2))
{
MyEdge.count--;
for(intk=1;k<=edgeSet.size();k++)
{
if(edgeSet.get(k).equals(newEdge2))
{
edgeSet.get(k).addUseCount();
break;
}
}
}else
edgeSet.put(newEdge2.id,newEdge2);
//对第三边进行处理
this.addUseCount();
this.turnBeginAndEnd();
//生成三角形,并加入到三角形集合中
MyTrianglenewTriangle=newMyTriangle(this.getBeginPoint(pointSet),goodPoint,this.getEndPoint(pointSet),edgeSet);
triangleSet.put(newTriangle.id,newTriangle);
break;
}
}
returngoodPoint;
}
/*
*此方法是将某一点与当前边的顶点角的余弦值返回
*/
privatedoublegetCos(MyPointp,MappointSet)
{
PointOA=newPoint(pointSet.get(this.begin).x-p.x,pointSet.get(this.begin).y-p.y);
PointOB=newPoint(pointSet.get(this.end).x-p.x,pointSet.get(this.end).y-p.y);
doubleOALength=Math.sqrt(OA.x*OA.x+OA.y*OA.y);
doubleOBLength=Math.sqrt(OB.x*OB.x+OB.y*OB.y);
return(OA.x*OB.x+OA.y*OB.y)/(OALength*OBLength);
}
}
importjava.util.*;
importjava.io.*;
publicclassMyPoint{
publicstaticintcount=0;
publicintid;
publicintx;
publicinty;
privateStringinfo;
publicMyPoint(intx,inty)
{
this.id=++count;
this.x=x;
this.y=y;
}
publicvoidsetInfo(Stringinfo)
{
this.info=info;
}
publicStringgetInfo()
{
returnthis.info;
}
publicdoubledistance(intx,inty)
{
inttempx=(this.x-x)*(this.x-x);
inttempy=(this.y-y)*(this.y-y);
returnMath.sqrt((tempx+tempy));
}
publicdoubledistance(MyPointp)
{
inttempx=(this.x-p.x)*(this.x-p.x);
inttempy=(this.y-p.y)*(this.y-p.y);
returnMath.sqrt((tempx+tempy));
}
/*
*下面这个方法是找寻主叫点在点集中与之最近的点
*返回的是与之最近点的引用
*/
publicMyPointgetMinDistancePoint(MappointSet)
{
intminID=this.id;
doubleminDistance=Double.MAX_VALUE;
for(inti=1;i<=pointSet.size();i++)
{
if(i==this.id)continue;
doubletemp=this.distance(pointSet.get(i));
if(minDistance>temp)
{
minDistance=temp;
minID=i;
}
}
returnpointSet.get(minID);
}
/*
*下面的方法是将点集中的点全部输出到文件中
*/
publicstaticbooleansavePoints(MappointSet)
{
booleanflag=false;
Filefile=newFile("point.txt");
try
{
PrintStreamps=newPrintStream(file);
PrintStreamtemp=System.out;
System.setOut(ps);
for(inti=1;i<=pointSet.size();i++)
System.out.println(pointSet.get(i).id+"\t"+pointSet.get(i).x+"\t"+pointSet.get(i).y);
flag=true;
System.setOut(temp);
//temp.close();
ps.close();
}catch(IOExceptione)
{
flag=false;
}
returnflag;
}
/*
*下面的方法是将文件中的点加载到内存中
*/
publicstaticbooleanreadPoints(MappointSet,Stringfilename)
{
booleanflag=false;
Filefile=newFile(filename);
try
{
FileInputStreamin=newFileInputStream(file);
Scannerfromfile=newScanner(in);
while(fromfile.hasNextInt())
{
fromfile.nextInt();
MyPointpoint=newMyPoint(fromfile.nextInt(),fromfile.nextInt());
pointSet.put(point.id,point);
}
flag=true;
in.close();
}catch(IOExceptione)
{
returnflag;
}
returnflag;
}
}
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;
importjava.util.*;
publicclassMyTinextendsJFrame
{
publicstaticvoidmain(String[]agrs)
{
MyTintin=newMyTin("三角网的生成");
}
privateMyPanelshow;
privateJButtonbegin;
publicMyTin(Stringtitle)
{
super(title);
this.setSize(500,580);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.show=newMyPanel();
this.show.setBounds(0,0,this.getWidth(),this.getHeight()-80);
this.begin=newJButton("开始绘制");
this.begin.addActionListener(newMyButtonMonitor(