1. 程式人生 > >Triangle2D類(Java)

Triangle2D類(Java)

定義Triangle2D類,包含:

  • 三個名為p1、p2和p3的MyPoint型資料域,這三個資料域都帶有get和set方法。MyPoint在練習題10.4中定義。
  • 一個無參構造方法,該方法建立三個座標為(0,0)、(1,1)和(2,5)的三個點組成的預設三角形。
  • 一個建立帶指定點的三角形構造方法。
  • 一個返回三角形面積的方法getArea()。
  • 一個返回三角形周長的方法getPerimeter()。
  • 如果給定的點p在這個三角形內,那麼方法contain(MyPoint p)返回true。如圖a所示。
  • 如果給定的三角形在這個三角形內,那麼方法contain(Triangle2D t)返回true。如圖b所示。
  • 如果給定的三角形和這個三角形重疊,那麼方法overlaps(Triangle2D t)返回true。如圖c所示。

 MyPoint實現起來很簡單,相信大家都會就不解釋了

一、MyPoint型資料域

          為了方便訪問三角形的頂點,這裡我沒有設定訪問器和修改器,用了一個數組,當然這樣的方法很不規範,能改的話最好還是改了吧。

二、無參構造方法,

          在此構造方法中直接對資料域進行賦值即可。

三、建立帶指定點的三角形構造方法。

          引數為3個MyPoint的物件

四、getArea()。

設A(x1,y1),B(x2,y2),C(x3,y3)           由A-->B-->C-->A 按逆時針方向轉。(行列式書寫要求)           設三角形的面積為S

                                      | x1 y1 1 |

          則S=(1/2)*         | x2 y2 1 | 

                                      | x3 y3 1 |

             S=(1/2)*(x1y2*1+x2y3*1+x3y1*1-x1y3*1-x2y1*1-x3y2*1)

          順時針需取絕對值

          即用三角形的三個頂點座標求其面積的公式為:

                 S=|(1/2)*(x1y2+x2y3+x3y1-x1y3-x2y1-x3y2)|

五、getPerimeter()。

          MyPoint提供了求兩點間距離的方法,可直接求三角形的三條邊,求和得到周長。

六、 contain(MyPoint p)

            注意:1、如果點剛好在三角形的邊上,那麼會出現一個三角形的面積為0,

                       2、由於面積是double型資料,double比較時精度會出現問題,所以這裡用Double類的compare方法。

七、contain(Triangle2D t)

            只需要保證三角形t的三個頂點都在此(this)三角形三角形中即可

八、overlaps(Triangle2D t)

            其實我這裡還有幾種特殊情況沒考慮.

public class Triangle2D {
	private MyPoint p[]=new MyPoint[3];
    public Triangle2D() {
    	p[0]=new MyPoint(0,0);
    	p[1]=new MyPoint(1,1);
    	p[2]=new MyPoint(2,5);
    }
    public Triangle2D(MyPoint... point){
    	p[0]=point[0];
    	p[1]=point[1];
    	p[2]=point[2];
    }
    public double getArea(){
    	return Math.abs(0.5*(p[0].x*p[1].y+p[1].x*p[2].y+p[2].x*p[0].y-p[0].x*p[2].y-p[1].x*p[0].y-p[2].x*p[1].y));
    }
    public double getPerimeter(){
    	return p[0].distance(p[1])+p[0].distance(p[2])+p[1].distance(p[2]);
    }
    public boolean contains(MyPoint p){	       //面積法判斷點在三角形內
    	double a=new Triangle2D(this.p[0],this.p[1],p).getArea();
    	double b=new Triangle2D(this.p[1],this.p[2],p).getArea();
    	double c=new Triangle2D(this.p[0],this.p[2],p).getArea();	
    	return Double.compare(a+b+c,this.getArea())==0&&a!=0&&b!=0&&c!=0;		//面積相等 並且 不存在面積為0的三角形
    }
    public boolean contains(Triangle2D t){      //保證三個頂點都在三角形內
    	return contains(t.p[0])&&contains(t.p[1])&&contains(t.p[2]);
    }
    public boolean judge(MyPoint a,MyPoint b,MyPoint c, MyPoint d){      //跨立實驗,向量叉乘
    	double AB_AC=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);
		double AB_AD=(d.x-a.x)*(b.y-a.y)-(b.x-a.x)*(d.y-a.y);
		double CD_CA=(a.x-c.x)*(d.y-c.y)-(d.x-c.x)*(a.y-c.y);
		double CD_CB=(b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);
    	return Double.compare(AB_AC*AB_AD,0)<0&&Double.compare(CD_CA*CD_CB,0)<0;
    }
    public boolean overlaps(Triangle2D t){
    	for(int i=0;i<2;i++)						//i、j從this三角形中獲取兩個點
    		for(int j=i+1;j<3;j++)
    			for(int a=0;a<2;a++)				//a、b從t三角形中從獲取兩個點
    				for(int b=a+1;b<3;b++)
    					if(judge(this.p[i],this.p[j],t.p[a],t.p[j])==true)
    						return true;
    	return false;
    }
    public static void main(String[] args) {
        Triangle2D t1=new Triangle2D(new MyPoint(2.5,2),new MyPoint(4.2,3),new MyPoint(5,3.5));
        System.out.println("area is : "+t1.getArea()+" Perimeter is : "+t1.getPerimeter());
        System.out.println(t1.contains(new MyPoint(3,3)));  
        System.out.println(t1.contains(new Triangle2D(new MyPoint(2.9,2),new MyPoint(4,1),new MyPoint(1,3.4)))); 
        System.out.println(t1.overlaps(new Triangle2D(new MyPoint(2.5,5),new MyPoint(4,-3),new MyPoint(2,6.5)))); 
       
    }
}
class MyPoint{
	public double x,y;
	public MyPoint(){
		x=0;y=0;
	}
	public MyPoint(double  x,double y){
		this.x=x;this.y=y;
	}
	public double distance(MyPoint other){
		return Math.sqrt(Math.pow(x-other.x,2)+Math.pow(y-other.y,2));
	}
	public double distance(int x,int y){
		return Math.sqrt(Math.pow(x-this.x,2)+Math.pow(y-this.y,2));
	}
}