java 多边形裁剪_使用java写的Sutherland_Hodgeman多边形裁剪算法

点的类,相信大家已经非常熟悉了

package pow;

/*点的类*/

public class Point {

public double x;

public double y;

public Point(double x,double y){

this.x = x;

this.y = y;

}

public Point(){

this.x = 0;

this.y = 0;

}

public void setX(double x){

this.x = x;

}

public void setY(double y){

this.y = y;

}

public double getX(){

return this.x;

}

public double getY(){

return this.y;

}

}

向量的类(线)

package pow;

/*向量的类*/

public class Vector {

Point start;

Point end;

public Vector(Point start,Point end){

this.start = start;

this.end = end;

}

}

算法主题,把数据写死了,大家可以把数据更改为输入:

package pow;

import java.util.ArrayList;

import java.util.List;

public class pow {

public static void main(String[] arg){

//初始化赋值过程

List points = new ArrayList();

Point point = new Point(0,0);

points.add(point);

point = new Point(7,2);

points.add(point);

point = new Point(5,9);

points.add(point);

point = new Point(3,8);

points.add(point);

point = new Point(0,1);

points.add(point);

List vectors = new ArrayList();

vectors.add(new Vector(new Point(8,0), new Point(8,6)));

vectors.add(new Vector(new Point(8,6), new Point(1,6)));

vectors.add(new Vector(new Point(1,6), new Point(1,0)));

vectors.add(new Vector(new Point(1,0), new Point(8,0)));

//利用算法求出切割后的顶点集合,代表新的多边形

List result = Sutherland_Hodgeman(points,vectors);

//将所有的节点打印出来

for(int k=0;k

System.out.println(result.get(k).getX()+"|"+result.get(k).getY());

}

}

//裁剪算法

public static List Sutherland_Hodgeman(List points,List vectors){

List result = new ArrayList();

List cur = new ArrayList();

int vectorsSize = vectors.size();

int pointSize = points.size();

Point S = points.get(pointSize-1);

//初始化操作的集合

for(int i=0;i

result.add(points.get(i));

}

boolean flag;

for(int j=0;j

//flag = false表示在内侧,flag = true表示在外侧

if(isInside(S,vectors.get(j)))

flag = false;

else

flag = true;

int resultSize = result.size();

for(int i=0;i

//证明其在当前vector的内

if(isInside(result.get(i),vectors.get(j))){

//如果前一个点在vector的外侧,那么将他们的交点加入到结果集中

if(flag){

flag = false;

cur.add(Intersection(S, result.get(i), vectors.get(j).start, vectors.get(j).end));

}

//并将当前节点加入到结果集中

cur.add(result.get(i));

}

else{

//前一个点在外侧吗?

if(!flag){

flag = true;

//如果前一个点在vector的内侧,那么将他们的交点加入到结果集中

cur.add(Intersection(S, result.get(i), vectors.get(j).start, vectors.get(j).end));

}

}

//更新首次比较的节点

S = result.get(i);

}

//将本次结果拷贝出来,作为下次对比的样本,并将本次结果进行清空

int resultLen = result.size();

result.clear();

for(int i=0;i

result.add(cur.get(i));

}

cur.clear();

}

return result;

}

//求一个点是否在一条边的内侧,在点序为逆时针的时候(如果点在线上,也算在内侧)

public static boolean isInside(Point p,Vector v){

return Multi(p,v.start,v.end)>=0?true:false;

}

//求叉积p0->p1与p0->p2的叉积

public static double Multi(Point p0,Point p1,Point p2){

return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);

}

public static Point Intersection(Point start0,Point end0,Point start1,Point end1){

//由正弦定理推出

double pX = (Multi(start0, end1, start1)*end0.x - Multi(end0, end1, start1)*start0.x)/

(Multi(start0, end1, start1) - Multi(end0, end1, start1));

double pY = (Multi(start0, end1, start1)*end0.y - Multi(end0, end1, start1)*start0.y)/

(Multi(start0, end1, start1) - Multi(end0, end1, start1));

return new Point(pX,pY);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值