2014-04-29 61 views
0

之間我的課,我們給出的任務如下:估算區域形狀

在這個作業中,你會嘗試一個程序計算一組形狀的重疊區域,實現蒙特卡洛積分,正如課堂討論的那樣。 製作AreaEstimator.java,該程序使用隨機估計來估計任意數量的圓和三角形的重疊區域。該程序的參數將是這個試驗中隨機生成的點的數量,接下來是定義這些形狀的點的座標。例如,

的java AreaEstimator百萬圈2.0 2.0 1.0 1.0三角形1.0 2.5 3.0 2.0 -3.0 2.5圈1.0 3.0

將產生百萬隨機點來估計三角形,其頂點是(1.0,1.0的重疊),(2.5,3.0),(2.0,-3.0),其中兩個圓的中心位於(2.0,2.0)和(2.5,1.0),其半徑分別爲1.0和3.0。

這裏是我的Circle類代碼:

public class Circle { 
private double xcenter; 
private double ycenter; 
private double radius; 
private double xcmax; 
private double xcmin; 
private double ycmax; 
private double ycmin; 


public Circle (double xcenter, double ycenter, double radius){ 
    if(radius <= 0){ 
     throw new IllegalArgumentException(); 
    } 
    this.xcenter = xcenter; 
    this.ycenter = ycenter; 
    this.radius = radius; 

} 
public void maxAndMinCircle(){ //find the minimun and maximum for the plane according to this circle 
    xcmax = (this.xcenter + this.radius); 
    ycmax = (this.ycenter + this.radius); 
    xcmin = (this.xcenter - this.radius); 
    ycmin = (this.ycenter - this.radius); 

} 
public double getXCMax(){ 
    return xcmax; 
} 
public double getYCMax() { 
    return ycmax; 
} 
public double getXCMin() { 
    return xcmin; 
} 
public double getYCMin(){ 
    return ycmin; 
} 

public boolean outsideCircle(double randX, double randY){ // find if the random point passed thru is in this circle 
    double distance = Math.sqrt((randX-this.xcenter)*(randX-this.xcenter) + (randY-this.ycenter) * (randY - this.ycenter)); 
    return distance >= radius; 
}} 

三角類:

public class Triangle { 
private double cornerx1; 
private double cornery1; 
private double cornerx2; 
private double cornery2; 
private double cornerx3; 
private double cornery3; 
private double xtmax; 
private double xtmin; 
private double ytmax; 
private double ytmin; 
private Double[] corners; 

public Triangle (double cornerx1, double cornery1, double cornerx2, double cornery2, double cornerx3, double cornery3){ 
    corners = new Double [6]; 
    corners[0] = cornerx1; 
    corners[1] = cornery1; 
    corners[2] = cornerx2; 
    corners[3] = cornery2; 
    corners[4] = cornerx3; 
    corners[5] = cornery3; 
} 
public void maxAndMinTriangle(){ // find the minimum and maximum of the plane according to this triangle 
    xtmax = corners[0]; 
    for(int i=1;i < corners.length;i += 2){ 
     if(corners[i] > xtmax){ 
      xtmax = corners[i]; 
     } 
    } 

    xtmin = corners[0]; 
    for(int i=1;i < corners.length;i += 2){ 
     if(corners[i] < xtmin){ 
      xtmin = corners[i]; 
     } 
    } 

    ytmax = corners[1]; 
    for(int i=1;i < corners.length;i += 2){ 
     if(corners[i] > ytmax){ 
      ytmax = corners[i]; 
     } 
    } 

    ytmin = corners[1]; 
    for(int i=1;i < corners.length;i += 2){ 
     if(corners[i] < ytmin){ 
      ytmin = corners[i]; 
     } 
    } 
} 
public double getXTMax(){ 
    return xtmax; 
} 

public double getYTMax() { 
    return ytmax; 
} 
public double getXTMin() { 
    return xtmin; 
} 
public double getYTMin(){ 
    return ytmin; 
} 


//public static boolean isLeft (double x1, double y1, double x2, double y2, double x3, double y3){ 
    //return (0 <= ((x2 - x1) * (y - y1))- ((y2 - y1) * (x - x1))); 
//} 

public boolean isLeft1 (double randX, double randY){ // find if this point is to the left of the first line 
    return (0 <= ((corners[2] - corners[0]) * (randY - corners[1]))- ((corners[3] - corners[1]) * (randX - corners[0]))); 
} 
public boolean isLeft2 (double randX, double randY){ // find if this point is to the left of the second line 
    return (0 <= ((corners[4] - corners[0]) * (randY - corners[1]))- ((corners[5] - corners[1]) * (randX - corners[0]))); 
} 
public boolean isLeft3 (double randX, double randY){ // find if this point is to the left of the third line 
    return (0 <= ((corners[4] - corners[2]) * (randY - corners[3]))- ((corners[5] - corners[3]) * (randX - corners[2]))); 
} 

public boolean outsideTriangle (double randX, double randY){ // find if this point is inside of the triangle 
    int counter = 0; 
    if (isLeft1(randX,randY)){ 
     counter++; 
    } 
    if (isLeft2(randX,randY)){ 
     counter++; 
    } 
    if (isLeft3(randX,randY)){ 
     counter++; 
    } 
    return counter == 2; // must be to the left of exactly 2 of the lines 
}} 

然後是AreaEstimator類:

public class AreaEstimator{ 


public static double[] maxAndMinValues (Circle[] circles,Triangle[] triangles){ 
// find maximum and minimum values according to all of the triangles and circles 
    double xmax = -100; 
    double ymax = -100; 
    double xmin = 100; 
    double ymin = 100; 
    for (int l=0; l < circles.length; l++){ 
     if (xmax < circles[l].getXCMax()){ 
      xmax = circles[l].getXCMax(); 
     } 
     if (ymax < circles[l].getYCMax()){ 
      ymax = circles[l].getYCMax(); 
     } 
     if (xmin > circles[l].getXCMin()){ 
      xmin = circles[l].getXCMin(); 
     } 
     if (ymin > circles[l].getYCMin()){ 
      ymin = circles[l].getYCMin(); 
     } 
    } 
    for (int m = 0; m < triangles.length; m++){ 
     if(xmax < triangles[m].getXTMax()){ 
      xmax = triangles[m].getXTMax(); 
     } 
     if(ymax < triangles[m].getYTMax()){ 
      ymax = triangles[m].getYTMax(); 
     } 
     if(xmin > triangles[m].getXTMin()){ 
      xmin = triangles[m].getXTMin(); 
     } 
     if(ymin > triangles[m].getYTMin()){ 
      ymin = triangles[m].getYTMin(); 
     } 
    } 
    double[] result = new double [4]; 
    result[0] = xmax; 
    result[1] = ymax; 
    result[2] = xmin; 
    result[3] = ymin; 
    return result; 
} 

public static void main (String[] args) { 
    double numThrows = Integer.parseInt(args[0]); // initialize amount of throws 
    if (numThrows <= 0){ 
     throw new IllegalArgumentException(); 
    } 

    int countCircles = 0; // find the amount of circles given 
    for (int i = 1; i<args.length; i++){ 
     if(args[i].equals("circle")){ 
      countCircles++;    
     } 
    } 

    Circle[] circles = new Circle [countCircles]; 

    for (int i = 1; i<args.length; i++){ 
     if (args[i].equals("circle")){ 
      for (int k = 0; k< countCircles; k++){ 
       double xcenter = Double.parseDouble(args[i+1]); 
       double ycenter = Double.parseDouble(args[i+2]); 
       double radius = Double.parseDouble(args[i+3]); 
       circles[k] = new Circle (xcenter, ycenter, radius); //values associated with this circle 
       circles[k].maxAndMinCircle();//max and min value of the circle itself 
      } 
     } 
    } 

    int countTriangles = 0; // find the amount of the triangles given 
    for (int i = 1; i < args.length; i++){ 
     if(args[i].equals("triangle")){ 
      countTriangles++; 
     } 
    } 

    Triangle[] triangles = new Triangle [countTriangles]; 

    for (int i = 1; i<args.length; i++){ 
     if (args[i].equals("triangle")){ 
      for (int p = 0; p< countTriangles; p++){ 
       double cornerx1 = Double.parseDouble(args[i+1]); 
       double cornery1 = Double.parseDouble(args[i+2]); 
       double cornerx2 = Double.parseDouble(args[i+3]); 
       double cornery2 = Double.parseDouble(args[i+4]); 
       double cornerx3 = Double.parseDouble(args[i+5]); 
       double cornery3 = Double.parseDouble(args[i+6]); 

       triangles[p] = new Triangle (cornerx1, cornery1, cornerx2, cornery2, cornerx3, cornery3); 
       //values associated with this triangle 
       triangles[p].maxAndMinTriangle(); //max and min value of the triangle itself 
      } 
     } 
    } 


    boolean dartsInOverlap = true; 
    double countInOverlap = 0; // initialize amount of darts in the overlapping shape 
    double[]result = maxAndMinValues(circles,triangles); 

    for(int i= 0;i < numThrows;i++){ 
     double randX= (Math.random() * (result[0]-result[2]) + result[2]) ; // generate a random x value 
     double randY= (Math.random() * (result[1]-result[3])+ result[3]); // generate a random y value 



     for (int h = 0; h < circles.length && dartsInOverlap; h++){ 
      if (circles[h].outsideCircle(randX, randY)){ 
       dartsInOverlap = false; // if the point is outside of the circle, it returns false 
      } 
     } 
     for (int q = 0; q < triangles.length && dartsInOverlap; q++){ 
      if (triangles[q].outsideTriangle(randX, randY)){ 
       dartsInOverlap = false; // if the point is outside of the triangle, it returns false 
      } 
     } 
     if (dartsInOverlap){ 
      countInOverlap++; // counts up the amount of points in the overlapping shape 
     } 
     dartsInOverlap = true; 
    } 
    System.out.println("This many darts were in the overlap between the shapes:" + countInOverlap); 
    // counts up the amount of points in the overlapping shape 
    System.out.println("The estimated overlapped areas is" + (result[0]-result[2])*(result[1]-result[3]) *(countInOverlap/numThrows)); 
    //finds estimated area 
}} 

我的代碼工作對於少數測試用例,如果在命令行中只有一個進入的圓圈和三角形,或者只有一個唯一的圓圈。一個三角形本身或任何其他組合將給我的答案遠離所需的區域估計。我查看並審查了我的代碼,這一切似乎都合乎邏輯。那麼,在我的代碼中,問題仍然存在?任何幫助,將不勝感激。

回答

0

maxAndMinTriangle至少有一個錯字。你寫了一個,你需要一個

xtmax = corners[0]; 
for(int i=1;i < corners.length;i += 2){ 
... 
xtmin = corners[0]; 
for(int i=1;i < corners.length;i += 2){ 

應該

xtmax = corners[0]; 
for(int i=0;i < corners.length;i += 2){ 
... 
xtmin = corners[0]; 
for(int i=0;i < corners.length;i += 2){