import java.util.ArrayList;
import java.util.Arrays;
public class Cloud {
private ArrayList<Point> points;
private double left;
private double right;
private double top;
private double bottom;
private final double epsilon = 10e-6;
/**
*
* @param p a Point
* @return whether p in the cloud
*/
public boolean hasPoint(Point p) {
return points.contains(p);
}
/**
* Constructor
* @param maxSize: points array size
*/
public Cloud(){
points = new ArrayList<Point>();
this.left = 0.0;
this.right = 0.0;
this.top = 0.0;
this.bottom = 0.0;
}
/**
*
* @param p
* if (size < maxSize) add p to points, increment size
* @return the boolean value returned by the ArrayList add method
*
*/
public boolean addPoint(Point p){
extremes();
return points.add(p);
}
/**
* Use the method toString of ArrayList
*/
public String toString(){
return points.toString();
}
/*
* return an array of the double extremes instance variables:
* left, right, top, bottom
*/
public double[] getExtremes(){
double[] ext = new double[4];
ext[0] = left;
ext[1] = right;
ext[2] = top;
ext[3] = bottom;
return ext;
}
/**
* Compute four double values:
* left: the x coordinate of a left-most Point
* right: the x coordinate of a right-most Point
* top: the y coordinate of a highest Point
* bottom: the y coordinate of a lowest Point
*
* and put them in the appropriate instance variables
*/
private void extremes(){
for (int i=0; i<points.size(); i++){
Point p = points.get(i);
if(p.getX() < left){
left = p.getX();
}
if(p.getX() > right){
right = p.getX();
}
if(p.getY() < bottom){
bottom = p.getY();
}
if(p.getY() > top){
top = p.getY();
}
}
}
/**
*
* @param p1
* @param p2
*
* all Points outside the rectangle, line or point spanned
* by p1 and p2 are removed
*
* After removal, the extreme values left, right, top and bottom
* are updated using the extremes method; then using an assert the
* extremes of the Cloud are checked using the extremes of the two
* Points p1, and p2
*
*/
public void crop(Point p1, Point p2){
if(p1 == p2){
Point temp = p1;
points.clear();
points.add(temp);
}
if(p1.getX() == p2.getX()){
double temp = p1.getX();
for(int i=0; i<points.size(); i++){
if(points.get(i).getX() != temp){
points.remove(i);
}
}
}
if(p1.getY() == p2.getY()){
double temp = p1.getY();
for(int i=0; i<points.size(); i++){
if(points.get(i).getY() != temp){
points.remove(i);
}
}
}
else{
double tempLeft = p1.getX();
double tempRight = p1.getX();
double tempTop = p1.getY();
double tempBottom = p1.getY();
if(p2.getX() < tempLeft){
tempLeft = p2.getX();
}
if(p2.getX() > tempRight){
tempRight = p2.getX();
}
if(p2.getY() > tempTop){
tempTop = p2.getY();
}
if(p2.getY() < tempBottom){
tempBottom = p2.getY();
}
for(int i=0; i<points.size(); i++){
if(points.get(i).getX() < tempLeft){
points.remove(i);
}
if(points.get(i).getX() > tempRight){
points.remove(i);
}
if(points.get(i).getY() < tempBottom){
points.remove(i);
}
if(points.get(i).getY() > tempTop){
points.remove(i);
}
}
}
}
/*
* equality check for doubles
*/
private boolean dblEq(double a, double b){
return Math.abs(a-b) < epsilon;
}
/**
* @param args: not used
*/
public static void main(String[] args) {
// TODO test all cloud methods
Cloud set = new Cloud();
System.out.println("initial set: " + set);
for(int i=0; i<5; i++)
for (int j=0; j<i; j++){
set.addPoint(new Point(i-j*0.5,j));
}
System.out.println("set after addPoints: " + set);
double[] ext = set.getExtremes();
if(ext != null) {
System.out.println("extremes: " + Arrays.toString(ext));
System.out.println("left of set: " + ext[0]);
System.out.println("right of set: " + ext[1]);
System.out.println("top of set: " + ext[2]);
System.out.println("bottom of set: " + ext[3]);
set.crop(new Point(3,0), new Point(2,2));
System.out.println("set after crop 1: " + set);
assert set.dblEq(set.left,2.0) && set.dblEq(set.right,3.0) &&
set.dblEq(set.bottom,0.0) && set.dblEq(set.top,2.0);
set.crop(new Point(3,2),new Point(2,2));
System.out.println("set after crop 2: " + set);
assert set.dblEq(set.left,2.0) && set.dblEq(set.right,3.0) &&
set.dblEq(set.bottom,2.0) && set.dblEq(set.top,2.0);
}
}
}
Are here’s the output:
initial set: []
set after addPoints: [(1.0,0.0), (2.0,0.0), (1.5,1.0), (3.0,0.0), (2.5,1.0), (2.0,2.0), (4.0,0.0), (3.5,1.0), (3.0,2.0), (2.5,3.0)]
extremes: [0.0, 4.0, 2.0, 0.0]
left of set: 0.0
right of set: 4.0
top of set: 2.0
bottom of set: 0.0
set after crop 1: [(2.0,0.0), (3.0,0.0), (2.5,1.0), (2.0,2.0), (3.5,1.0), (3.0,2.0)]
set after crop 2: [(3.0,0.0), (2.0,2.0), (3.0,2.0)]
As you can see the extremes are not correct (the top of the set should be 3.0) , as well as it’s not cropping the correct values ether. What did I do wrong?
Edit:
Alright so basically my program is suppose to add “points” (two double values) to a “cloud” and set the extremes (the farthest and the least farthest from top the bottom of my cloud, as if it was a graph) and then go through and crop (set two points and get rid of all the points not in the square that is drawn by the given two points). I hope this helps.
In your add point you first calc the extreme and then add the point, so your last point is not included in that extreme.
public boolean addPoint(Point p){
extremes();
return points.add(p);
}
b.t.w why you don’t check the extreme on the point added instead of running it on the entire set.
The only change can be cause by the last point added.
you build the cloud in O(n^2) instead of O(n)
Roni