import java.util.Random; public class AvgArea { private double max_x; private double max_y; private int numTrials; private Random rGen; public AvgArea(int trials, double xmax, double ymax) { rGen = new Random(); numTrials = trials; max_x = xmax; max_y = ymax; } private Point randomPoint() { double x = rGen.nextDouble() * max_x; double y = rGen.nextDouble() * max_y; return new Point(x, y); } public double calculateAverage() { double sumOfAreas = 0.0; for (int i = 0; i < numTrials; i++) { Point A = randomPoint(); Point B = randomPoint(); Point C = randomPoint(); Triangle t = new Triangle(A, B, C); if (t.isValid() == false) { if (i!=0) i--; continue; } sumOfAreas += t.area(); } double avgArea = sumOfAreas / numTrials; return avgArea; } } /* * fun with looking at average areas of triangles over varied * x,y positive constraints. * * though, after i wrote this... i found: * http://mathworld.wolfram.com/SquareTrianglePicking.html * which made me not so stoked :-) but kinda stoked cuz this was something * done before. * * (c) 2008 Andrew R. Reiter , */ import java.util.Random; import java.text.DecimalFormat; public class AvgTrials { public static void main(String[] args) { int constraintsTrials = 100; int averageTrials = 1000; if (args.length == 2) { constraintsTrials = Integer.parseInt(args[0]); averageTrials = Integer.parseInt(args[1]); } Random r = new Random(); double rcount = 0.0; for (int i = 0; i < constraintsTrials; i++) { double xmax = r.nextDouble() * 10000.0; double ymax = r.nextDouble() * 10000.0; AvgArea aa = new AvgArea(averageTrials, xmax, ymax); System.out.println("(x,y) range: (0,0)-("+ xmax+", "+ymax+"):"); double xyarea = xmax*ymax; double tarea = aa.calculateAverage(); double tdivxy = tarea / xyarea; double adiff = xyarea - tarea; System.out.println("\tx/y area: "+xyarea+ ", average triangle area: "+tarea); System.out.println("\tarea diff: "+adiff+ ", (triangle area) / (xy area): "+tdivxy); rcount += tdivxy; // Trip up Random() constructor a bit... // this is set at 1/10 a second for now.. // but do whatevs try { Thread.currentThread().sleep(100); } catch (Exception e) { } } double avgTxy = rcount / constraintsTrials; System.out.println("Average t-area/xy-area: "+avgTxy); DecimalFormat df = new DecimalFormat("0.000%"); System.out.println("This means, given a random triangle made of 3 random points with varying x,y constraints, the triangle will cover "+ df.format(avgTxy)+" of the random (0,0)-(x,y) square"); } } /* * Simple 2-D Point. * * (c) 2008 Andrew R. Reiter , */ public class Point { private double x, y; public Point(double x, double y) { this.x = x; this.y = y; } public double x() { return x; } public double y() { return y; } public String toString() { return "("+x+", "+y+")"; } } So, I was doing this, then figured someone else prolly has... duh: http://mathworld.wolfram.com/SquareTrianglePicking.html -- I also did this for areas of circles contained entirely within the x,y constraints.. (that is... center + radius in any direction is always within the plane). Prior to doing this, I predicted that there would be alittle less than 2 times this 0.07... number. which was about right. why? well, think about overlapping the largest circle in the x,y plane with the largest triangle in the x,y plane... and think. if I recall, the # was about 0.126 or somethign _ . / X| | / | \/__/| /* * Simple Triangle based on 3 given 2-D Points. * * (c) 2008 Andrew R. Reiter , */ public class Triangle { private Point a, b, c; public Triangle(Point A, Point B, Point C) { a = A; b = B; c = C; } /* * I wasn't sure the best approach... so, I decided to try the * angle between two vectors method... i had another method * before, but i didn't like so much. */ public boolean isValid() { double distAB = distance(a, b); double dx = b.x() - a.x(); double dy = b.y() - a.y(); double distBC = distance(b, c); double dx2 = c.x() - b.x(); double dy2 = c.y() - b.y(); double dotx = dx*dx2; double doty = dy*dy2; double dot = dotx+doty; double dst = distAB*distBC; double angarg = dot/dst; // Basically, let's just have some sanity about dealing // with distance(). if (Math.abs((1-angarg)) <= 0.0000001) { angarg = 1; } if (Math.acos(angarg) == 0) { return false; } return true; } /* public static void main(String[] args) { Point p1 = new Point(0,0); Point p2 = new Point(1,1); Point p3 = new Point(2,2); Triangle t = new Triangle(p1,p2,p3); if (t.isValid() == false) { System.out.println("Correct, this is not a triangle"); } else { System.out.println("WRONG, this is not a triangle"); } Point p4 = new Point(2,3); t = new Triangle(p1,p2,p4); if (t.isValid() == true) { System.out.println("Correct, this is a triangle"); } else { System.out.println("WRONG, this is a triangle"); } } */ // Sqroot( (p2.x-p1.x)^2 + (p2.y-p1.y)^2 ) public double distance(Point p1, Point p2) { double dx = p2.x() - p1.x(); double dy = p2.y() - p1.y(); double dx_sq = Math.pow(dx, 2.0); double dy_sq = Math.pow(dy, 2.0); double sq_sum = dx_sq + dy_sq; return Math.sqrt(sq_sum); } /* * Area using Heron's Formula. * 1. calculate p, the sum of the edge lengths divided by 2. * 2. the area is the sqroot(p*(p-edge1)(p-edge2)(p-edge3)) * Seemed easier to me than figuring out a orthogonal vector to * one vertice from a "base" .. and then calculating 1/2*base*height * */ public double area() { double d1, d2, d3; d1 = distance(a, b); d2 = distance(b, c); d3 = distance(c, a); double p = (d1+d2+d3) / 2; double sq = p*(p-d1)*(p-d2)*(p-d3); return Math.sqrt(sq); } }