📄 polygondx.java
字号:
}
}
////////////////////////////////////////////////////////////////////////////////
// Weiler_Athenton裁剪算法(内裁剪)步骤:
//1、建立主多边形和裁剪多边的顶点表;
//2、求主多边形和裁剪多边形的交点,并将这些交点按顺序插入两多边形的顶点表中。
//在两多边表形顶点表中的相同交点间建立双向指针;
//3、裁剪:如果存在没有被跟踪过的交点,执行以下步骤:
//(1)建立裁剪结果多边形的顶点表;
//(2)选取任一没有被跟踪过的交点为始点,将其输出到结果多边形顶点表中;
//(3)如果该交点为进点,跟踪主多边形边边界;否则跟踪裁剪多边形边界;
//(4)跟踪多边形边界,每遇到多边形顶点,将其输出到结果多边形顶点表中,直至遇到新的交点.
//(5)将该交点输出到结果多边形顶点表中,并通过连接该交点的双向指针改变跟踪方向
//(如果上一步跟踪的是主多边形边界,现在改为跟踪裁剪多边形边界;
//如果上一步跟踪裁剪多边形边界,现在改为跟踪主多边形边界);
//(6)重复(4)、(5)直至回到起点.
void WAClip(int style,Point p0,Point p3){
//1、建立主多边形和裁剪多边的顶点表;主多边形 vPoint
//裁剪多边的顶点表vClip
Vector vClip = new Vector();
Point s = new Point(p3.x,p0.y);
Point p = new Point(p0.x,p3.y);
vClip.add(p0);vClip.add(s);vClip.add(p);vClip.add(p3);
//2、求主多边形和裁剪多边形的交点,并将这些交点按顺序插入两多边形的顶点表中。
//每一条边与vClip的四条边求交点
int InLength = vPoint.size();
s = (Point)(vPoint.elementAt(InLength - 1));//取最后一点
for (int j=0;j<InLength;j++){
p = (Point) (vPoint.elementAt(j)); //取s前一点
// if (Inside0(p, vClip)) {
}
}
//////////////////////////////////////////////////////////////////////////////]
//输入是否在裁剪多边形内
boolean Inside0(Point p,Vector v) {
Point p0,p3;
p0 = (Point)(v.elementAt(0));
p3 = (Point)(v.lastElement());
if ((p.x<p3.x)&&(p.x>p0.x)&&(p.y>p0.y)&&(p.y<p3.y)) return true;
return false;
}
///////////////////////////////////////////////////////////////////////////////
//该算法的基本思想是逐边裁剪、两次分解、流水线作业:
//首先将多边形对于矩形窗口的裁剪分解为对窗口四边所在直线的裁剪,
//其次,将多边形对一条直线的裁剪分解为各边对直线的裁剪。
//法的每一步,考虑窗口的一条边以及延长线构成的裁剪线。
//该线把平面分成两个部分:一部分包含窗口,称为可见一侧;
//另一部分称为不可见一侧。依序考虑多边形的各条边的两端点S、P。
//它们与裁剪线的位置关系只有四种。(1)S,P均在可见一侧
//(2)S,P均在不可见一侧(3)S可见,P不可见(4)S不可见,P可见。
//每条线段端点S、P与裁剪线比较之后,可输出0至2个顶点。
//对于情况(1)仅输出顶点P;情况(2)输出0个顶点;情况(3)输出线段SP与裁剪线的交点I;
//情况(4)输出线段SP与裁剪线的交点I和终点P.
//上述算法仅用一条裁剪边对多边形进行裁剪,得到一个顶点序列,
//作为下一条裁剪边处理过程的输入。对于每一条裁剪边,算法框图一样,
//只是判断点在窗口哪一侧以及求线段SP与裁剪边的交点算法应随之改变。
void SHClip(int style,Point p0,Point p3, DrawPanel Panel) {
//style ==0 clip; style == 1 demo;
//p0 is the clip window's vertex;p1 is another vertex
Vector OutVertexArray ;
Vector ClipBoundary = new Vector();
Point p1 = new Point(p3.x,p0.y);
Point p2 = new Point(p0.x,p3.y);
ClipBoundary.add(p1);
ClipBoundary.add(p0);
OutVertexArray = SutherlandHodgmanClip(vPoint, ClipBoundary);
if (1==style) {
drawOutVertex(p0,p3,OutVertexArray,Panel );
}
ClipBoundary.clear();
ClipBoundary.add(p3);
ClipBoundary.add(p1);
OutVertexArray = SutherlandHodgmanClip(OutVertexArray,ClipBoundary);
if (1==style) {
drawOutVertex(p0,p3,OutVertexArray,Panel );
}
ClipBoundary.clear();
ClipBoundary.add(p0);
ClipBoundary.add(p2);
OutVertexArray = SutherlandHodgmanClip(OutVertexArray,ClipBoundary);
if (1==style) {
drawOutVertex(p0,p3,OutVertexArray,Panel );
}
ClipBoundary.clear();
ClipBoundary.add(p2);
ClipBoundary.add(p3);
OutVertexArray = SutherlandHodgmanClip(OutVertexArray,ClipBoundary);
drawOutVertex(p0,p3,OutVertexArray,Panel );
}
//////////////////////////////////////////////////////////////////////////////
void drawOutVertex(Point p0,Point p3,Vector OutVertexArray,DrawPanel Panel ) {
Panel.big.clearRect(0, 0, Object2D.cWidth, Object2D.cHeight);
Panel.big.setColor(Color.RED);
Panel.big.drawRect(p0.x, p0.y, Math.abs(p3.x - p0.x),
Math.abs(p3.y - p0.y));
Point s,p;
int l,j= OutVertexArray.size();
Panel.big.setColor(ForeColor);
for (int i = 0; i < j; i++) {
s = (Point) (OutVertexArray.elementAt(i));
l = i + 1;
if (l == j)
l = 0;
p = (Point) (OutVertexArray.elementAt(l));
Panel.big.drawLine(s.x, s.y, p.x, p.y);
}
Panel.repaint();
}
///////////////////////////////////////////////////////////////////////////////
Vector SutherlandHodgmanClip(Vector InVertexArray, Vector ClipBoundary ) {
Point s,p,ip;//一边的起始点与结束点,交点
int j;
int Outlegth = 0 ;
int InLength = InVertexArray.size();
Vector OutVertexArray = new Vector();
s = (Point)(InVertexArray.elementAt(InLength - 1));//取最后一点
for (j=0;j<InLength;j++){
p = (Point) (InVertexArray.elementAt(j)); //取s前一点
if (Inside(p, ClipBoundary)) {
if (Inside(s, ClipBoundary)) { //SP在窗口内,情况1
OutVertexArray.add(p);
System.out.println("SP在窗口内,情况1");
System.out.println("p.x="+p.x+",p.y="+p.y);
System.out.println("s.x="+s.x+",s.y="+s.y);
}
else {
ip = Intersect(s, p, ClipBoundary);//情况4
OutVertexArray.add(ip);
OutVertexArray.add(p);
System.out.println("情况4");
System.out.println("ip.x="+ip.x+",ip.y="+ip.y);
System.out.println("p.x="+p.x+",p.y="+p.y);
}
}
else if (Inside (s,ClipBoundary)) { //S在窗口内,P在窗口外,情况3
ip = Intersect (s, p, ClipBoundary);
OutVertexArray.add(ip);
System.out.println("情况3");
System.out.println("ip.x="+ip.x+",ip.y="+ip.y);
} //情况2没有输出
s = p;
}
return OutVertexArray;
}
////////////////////////////////////////////////////////////////////////////////////
boolean Inside (Point Pt, Vector ClipBoundary)//判点在窗口内
{
Point tmp0,tmp1;
tmp0 = (Point)(ClipBoundary.elementAt(0));
tmp1 = (Point)(ClipBoundary.elementAt(1));
System.out.println("tmp0.x="+tmp0.x+",tmp0.y="+tmp0.y);
System.out.println("tmp1.x="+tmp1.x+",tmp1.y="+tmp1.y);
if (tmp1.x > tmp0.x) {//裁剪边为窗口下边
if (Pt.y <= tmp0.y){
System.out.println("pt.x=" + Pt.x + ",pt.y=" + Pt.y + "裁剪边为窗口下边,true");
return (true);
}
}
else if(tmp1.x< tmp0.x) {//裁剪边为窗口上边
if(Pt.y>= tmp0.y){
System.out.println("pt.x=" + Pt.x + ",pt.y=" + Pt.y + "裁剪边为窗口上边,true");
return true;
}
}
else if(tmp1.y< tmp0.y) {//裁剪边为窗口右边
if(Pt.x<= tmp0.x){
System.out.println("pt.x=" + Pt.x + ",pt.y=" + Pt.y + "裁剪边为窗口右边,true");
return true;
}
}
else if(tmp1.y> tmp0.y) {//裁剪边为窗口左边
if(Pt.x>= tmp0.x) {
System.out.println("pt.x=" + Pt.x + ",pt.y=" + Pt.y + "裁剪边为窗口左边,true");
return true;
}
}
System.out.println("pt.x=" + Pt.x + ",pt.y=" + Pt.y + "false");
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////
//直线段SP和窗口边界求交,返回交点;
Point Intersect (Point s,Point p,Vector ClipBoundary)
{
Point tmp0,tmp1;
Point IntersectPt = new Point(0,0);
tmp0 = (Point)(ClipBoundary.elementAt(0));
tmp1 = (Point)(ClipBoundary.elementAt(1));
if(tmp0.y== tmp1.y){//水平裁剪边
IntersectPt.y = tmp0.y;
IntersectPt.x = s.x+( tmp0.y -s.y)*(p.x - s.x) / (p.y - s.y);
}
else {//垂直裁剪边
IntersectPt.x = tmp0.x;
IntersectPt.y = s.y + (tmp0.x - s.x)*(p.y - s.y) / (p.x - s.x);
}
return IntersectPt;
}
/////////////////////////////////////////////////////////////////////////////////
public void scale(double sx, double sy) {
int j = vPoint.size();
Point s;
for ( int i=0;i<j;i++){
s = (Point)(vPoint.elementAt(i));
s.x =(int)(s.x*sx);
s.y =(int)(s.y*sy);
}
}
public void rotate(double theta, int x, int y) {
double c,s,a,b;
c = Math.cos(theta); s = Math.sin(theta);
int oldx,oldy;
a = x*(1-c)+y*s; b = y*(1-c)-x*s;
int j = vPoint.size();
Point s0;
for ( int i=0;i<j;i++){
s0 = (Point)(vPoint.elementAt(i));
oldx = s0.x; oldy = s0.y;
s0.x = (int)(oldx*c-oldy*s+a);
s0.y = (int)(oldx*s+oldy*c+b);
}
}
public void translate(int x, int y){
int j = vPoint.size();
Point s;
for ( int i=0;i<j;i++){
s = (Point)(vPoint.elementAt(i));
s.x +=x;
s.y +=y;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -