CDMS/src/CDMS/kscheck
diff -u -r1.4 -r1.5
--- SortCoordsTest.java 25 Jan 2011 23:43:29 -0000 1.4
+++ SortCoordsTest.java 28 Jan 2011 23:41:04 -0000 1.5
@@ -18,10 +18,14 @@
public static void main(String[] args) throws FileNotFoundException, IOException {
System.out.println("testing!");
//SortCoordsFile pcfile = new SortCoordsFile("side1_copy.txt","sortedCoords.txt");
- CreateRoadMapFile roadmap1 = new CreateRoadMapFile("/Users/maxinion/Documents/Work/CDMS/code/imaging/sortedCoords_long.txt","/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-25/autorun_long.csv",0.00059,1);
+ //CreateRoadMapFile roadmap1 = new CreateRoadMapFile("/Users/maxinion/Documents/Work/CDMS/code/imaging/sortedCoords_long.txt","/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-25/autorun_long.csv",0.00059,1);
//CreateRoadMapFile roadmap2 = new CreateRoadMapFile("shortTest2.txt","testautorun2.txt",0.00067);
//CreateRoadMapFile roadmap3 = new CreateRoadMapFile("longTest.txt","testautorun3.txt",0.00067);
//SplitSortedFile splitfile = new SplitSortedFile("sortedCoords.txt","splittest.txt");
+ SortCoordsFile pcfile = new SortCoordsFile("/Users/maxinion/Documents/Work/CDMS/code/imaging/side1_copy.txt","/Users/maxinion/Documents/Work/CDMS/code/imaging/testfiles1-28/sortedCoords_test_beta.csv");
+ if(pcfile.getInputStatus()==true){
+ pcfile.sortBeta();
+ pcfile.printOut(1);
+ }
}
-
}
CDMS/src/CDMS/kscheck
diff -u -r1.2 -r1.3
--- SortCoordsFile.java 22 Jan 2011 19:08:28 -0000 1.2
+++ SortCoordsFile.java 28 Jan 2011 23:41:04 -0000 1.3
@@ -19,18 +19,35 @@
* Note: requires blank line as last line of input file
* Ignores everything on a line after %
* Blank lines are safe, ignored
+ * Usage: construct, sort, print. sort kills the input'ed coordinate list: create a new object
+ * to sort your list again. bool getInputStatus tells us if there is a list ready to be sorted.
*/
public class SortCoordsFile {
+ private static double RIGHT_CUTOFF = 500;
+ private static double BIG_CUTOFF = 2000;
+
+ int ncoords;
private List<Double[]> _coordinates;
- public List<Double[]> sortedCoords;
-
+ private List<Double[]> sortedCoords;
+ private List<Double[]> nextCoords;
+ FileWriter fw;
+ FileReader fr;
+
+ /**
+ * Constructor: takes in inputCoordsFile and parses to a list.
+ * @param inputCoordsFile
+ * @param outputSortedFile
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
public SortCoordsFile(String inputCoordsFile, String outputSortedFile) throws FileNotFoundException, IOException {
// Open the autorun file and setup a StreamTokenizer for a space delimited list
- FileReader fr = new FileReader(inputCoordsFile);
- FileWriter fw = new FileWriter(outputSortedFile);
- BufferedWriter output = new BufferedWriter(fw);
+ fr = new FileReader(inputCoordsFile);
+ fw = new FileWriter(outputSortedFile);
+
+
StreamTokenizer tok = new StreamTokenizer(fr);
tok.resetSyntax();
tok.wordChars(33, 126);//normal text are words
@@ -64,14 +81,74 @@
// if it's blank, we'll just continue on
}
System.out.println("out of loop?");
- int ncoords = _coordinates.size();
+
+ ncoords = _coordinates.size();
if(ncoords==0){
//quick error check on reading data
- output.close();
System.out.println("Is input setup correctly? 0 arguments.");
- return;
+ }
+ return;
+ }
+
+ public boolean getInputStatus(){
+ if(ncoords == 0){
+ return false;
+ }
+ return true;
+ }
+
+ public void printOut() throws IOException{
+ printOut(0);
+ }
+ public void printOut(int flag) throws IOException{
+
+ //write all elements in sortedCoords to the output file
+ BufferedWriter output = new BufferedWriter(fw);
+ Double[] coordsToAdd;
+ for(int k = 0; k < ncoords; k++){
+ coordsToAdd = sortedCoords.get(k);
+ Double x = coordsToAdd[0];
+ Double y = coordsToAdd[1];
+ Double angle = coordsToAdd[2];
+ Double type = coordsToAdd[3];
+ String xString = String.valueOf(x);
+ String yString = String.valueOf(y);
+ String angleString = String.valueOf(angle);
+ String typeString = String.valueOf(type);
+
+ if(flag == 0) output.write(xString+" "+yString+" "+angleString+" "+typeString+"\n"); //normal txt
+ else if(flag == 1) { //csv format for debugging
+ output.write(xString+","+yString+","+angleString+","+typeString);
+ if(k!=0){ // check that we're not at the first thing...
+ // we're not at the first one. there's going to be one behind. Check the distance.
+ Double[] next = sortedCoords.get(k-1);
+ Double x2 = next[0];
+ Double y2 = next[1];
+
+ Double dist = Math.pow(Math.pow(x-x2,2)+Math.pow(y-y2,2), 0.5);
+ output.write(","+String.valueOf(dist));
+ if(dist>1000){
+ output.write(",BIG JUMP");
+ }
+ if(dist>5000){
+ output.write("\n"); // skip a line for the hugest
+ }
+ }
+ output.write("\n");
+ } //close if on debug check
}
+
+ output.close();
+
+ }
+
+ /**
+ * First sorting method. Simply finds the things closest to each other, with no concern
+ * for how to deal with right angles and more complicated paths. Remember to printOut
+ * to actually get a txt file output of the sorted qet's.
+ */
+ public void sortAlpha(){
sortedCoords = new ArrayList<Double[]>();
//add first element of _coordinates to sortedCoords
@@ -82,7 +159,7 @@
//sort by looking for minimum distance between coords
- while(sortedCoords.size()<=ncoords){
+ while(sortedCoords.size()<ncoords){
double minDist = 10000000000.0;//some really large number
Double[] minCoords = {10000000000000.0,10000000000000.0,10000000000000.0,10000000000000.0};
//look at last element (most recently added) of sortedCoords
@@ -113,24 +190,334 @@
sortedCoords.add(minCoords);
}
-
- //write all elements in sortedCoords to the output file
- Double[] coordsToAdd;
- for(int k = 0; k < ncoords; k++){
- coordsToAdd = sortedCoords.get(k);
- Double x = coordsToAdd[0];
- Double y = coordsToAdd[1];
- Double angle = coordsToAdd[2];
- Double type = coordsToAdd[3];
- String xString = String.valueOf(x);
- String yString = String.valueOf(y);
- String angleString = String.valueOf(angle);
- String typeString = String.valueOf(type);
- output.write(xString+" "+yString+" "+angleString+" "+typeString+"\n");
- }
- output.close();
+
+ return;
}
-
+
+
+ /**
+ * New sorting method. Takes care of right angles in a smarter way (goes back to them after closing the loop
+ * or finding a dead end).
+ */
+ public void sortBeta(){
+ sortedCoords = new ArrayList<Double[]>();
+ nextCoords = new ArrayList<Double[]>();
+ //add first element of _coordinates to sortedCoords
+ //this becomes the first element in the sorted list
+ sortedCoords.add(_coordinates.get(0));
+ //remove this element from _coordinates
+ System.out.println("Before all, ncoords = " + _coordinates.size());
+
+ System.out.println("the last guy in coordinates is: " + _coordinates.get(_coordinates.size()-1)[0]);
+
+ _coordinates.remove(0);
+
+
+ //sort by looking for minimum distance between coords
+ while(sortedCoords.size()<ncoords){
+ double minDist = 10000000000.0;//some really large number
+ double minDist2 = 10000000000.0;
+ double minDist3 = 10000000000.0;
+ Double[] minCoords = {10000000000000.0,10000000000000.0,10000000000000.0,10000000000000.0};
+ Double[] minCoords2 = {0.0,0.0,0.0,0.0};
+ Double[] minCoords3 = {0.0,0.0,0.0,0.0};
+ //look at last element (most recently added) of sortedCoords
+ Double[] coords1 = sortedCoords.get(sortedCoords.size()-1);
+ Double x1 = coords1[0];
+ Double y1 = coords1[1];
+ //loop over all elements in _coordinates
+ for(int j = 0; j < _coordinates.size(); j++){
+ //get next coords for comparison
+ Double[] coords2 = _coordinates.get(j);
+ Double x2 = coords2[0];
+ Double y2 = coords2[1];
+ //calculate distance squared between coords1 and coords2
+ double dist = Math.pow(Math.pow((x1-x2),2)+Math.pow((y1-y2),2),0.5);
+ //assign coords2 to minCoords if the distance is smaller than previous
+ // distances and if coords2 is not already in sortedCoords
+ if(dist <= minDist && dist != 0.0){
+ if(sortedCoords.contains(coords2)==false && nextCoords.contains(coords2)==false){
+ // if it's already sorted, then it shouldn't be considered
+ // slide everything on down
+ minDist3 = minDist2;
+ minCoords3 = minCoords2;
+ minDist2 = minDist;
+ minCoords2 = minCoords;
+ minCoords = coords2;
+ minDist = dist;
+ }
+
+ }
+ else if(dist <= minDist2 && dist != 0.0){
+ if(sortedCoords.contains(coords2)==false && nextCoords.contains(coords2)==false){
+ // if it's already sorted, then it shouldn't be considered
+ // slide everything on down, less this time
+ minDist3 = minDist2;
+ minCoords3 = minCoords2;
+ minDist2 = dist;
+ minCoords2 = coords2;
+ }
+ }
+ else if(dist <= minDist3 && dist != 0.0){
+ if(sortedCoords.contains(coords2)==false && nextCoords.contains(coords2)==false){
+ // if it's already sorted, then it shouldn't be considered
+ // slide everything on down, less this time
+ minDist3 = dist;
+ minCoords3 = coords2;
+ }
+ }
+
+ }
+
+
+ //check the distance between current and the next, and the current and the next closest
+ //if the two are very similar, that means we're at a right angle: should be a large (qet size)
+ //value between "normal" qet's. Also, shouldn't be a big distance: these guys should be close to our
+ //current qet.
+ //System.out.println(String.valueOf(Math.abs(minDist2-minDist)));
+ //if(Math.abs(minDist2-minDist) < RIGHT_CUTOFF && minDist < BIG_CUTOFF){
+ // nextCoords.add(minCoords2); // add the guy at the right angle that we're not doing to to-do list
+ //System.out.println("added to do-list!"+String.valueOf(minCoords2));
+ //}
+ //System.out.println(String.valueOf(nextCoords.size()));
+
+ /*if(x1==1294&&y1==-29047){
+ System.out.print("closest for weirdo are: ");
+ System.out.print(minCoords[0]); System.out.print(" "); System.out.print(minCoords[1]);System.out.print("\n");
+
+
+ System.out.print("2nd closest for weirdo are: ");
+ System.out.print(minCoords2[0]); System.out.print(" "); System.out.print(minCoords2[1]);System.out.print("\n");
+
+ System.out.print("3rd closest for weirdo are: ");
+ System.out.print(minCoords3[0]); System.out.print(" "); System.out.print(minCoords3[1]);System.out.print("\n");
+
+ System.out.println("isStraight for 3rd: " + String.valueOf(isStraight(coords1,minCoords3)));
+ }*/
+
+ if(isStraight(coords1,minCoords3)!=0 && isStraight(coords1,minCoords2)==0 && isStraight(coords1,minCoords)==0 ){
+ // then we have a straight between current and not the closest 2
+ // put the closest on the to-do list, keep going straight though
+ System.out.println("Found a third-string match");
+ System.out.print(minCoords3[0]); System.out.print(" "); System.out.print(minCoords3[1]);System.out.print("\n");
+ sortedCoords.add(minCoords3);
+ boolean removestatus = _coordinates.remove(minCoords3);
+ System.out.println("removestatus on 3-0: " + String.valueOf(removestatus));
+ nextCoords.add(minCoords);
+ }
+ else if(isStraight(coords1,minCoords2)!=0 && isStraight(coords1,minCoords)==0){
+ // here, we have a straight between 2nd closest and the orig, and a right angle to closest
+ // move onto the straight, put the closest on the to-do
+ sortedCoords.add(minCoords2);
+ if(minCoords2[0]==1294) System.out.println("removing the devil-child");
+ boolean removestatus = _coordinates.remove(minCoords2);
+ System.out.println("removestatus on 2-0: " + String.valueOf(removestatus) + ", removed " +
+ String.valueOf(minCoords2[0]) + " " + String.valueOf(minCoords2[1]));
+ nextCoords.add(minCoords);
+ }
+ /*
+ else if(isStraight(coords1,minCoords2)==0 && isStraight(coords1,minCoords)!=0
+ && Math.abs(minDist2-minDist) < RIGHT_CUTOFF){
+ // here, a straight to the closest and a right angle to second closest,
+ // with the additional requirement that the distance between the two be very close
+ // want to be careful here, and only put the 2nd closest dude on the list if
+ // he's actually connected, which is what the RIGHT_CUTOFF is aiming for
+ sortedCoords.add(minCoords);
+ if(minCoords[0]==1294) System.out.println("removing the devil-child");
+ boolean removestatus = _coordinates.remove(minCoords);
+ System.out.println("removestatus on 0-2: " + String.valueOf(removestatus) + ", removed " +
+ String.valueOf(minCoords[0]) + " " + String.valueOf(minCoords[1]));
+ nextCoords.add(minCoords2);
+ }*/
+ // if the distance to the next qet is REALLY BIG that means we've reached a dead end or have
+ // looped back on ourselves. Either way, before we do a big huge jump to somewhere, check that
+ // we don't have anything on our to-do list.
+ else if(minDist > BIG_CUTOFF && nextCoords.size()>0){
+
+ Double[] removeme = nextCoords.remove(nextCoords.size()-1);
+ while(sortedCoords.contains(removeme)){
+ if(nextCoords.size() > 0) removeme = nextCoords.remove(nextCoords.size()-1);
+ else{
+ removeme = null;
+ break;
+ }
+ }
+ if(removeme!=null){
+ sortedCoords.add(removeme);
+
+ boolean removestatus = _coordinates.remove(removeme);
+ System.out.println("removestatus on jump: " + String.valueOf(removestatus));
+ System.out.println("jumped to to-do-list!"+String.valueOf(minCoords2));
+ }
+ }
+
+ else if(isStraight(minCoords,minCoords2) == isStraight(minCoords,minCoords3)
+ && isStraight(minCoords,minCoords2)!=0 && isStraight(coords1,minCoords)==0){
+ //we have a not straight between coords and mincoords
+ //BUT we have a straight between mincoords1-2-3. This means we've hit a straight line.
+ if(isStraight(minCoords,minCoords2) == 1){
+ // then we're vertical!
+ //if they're all on the same side, just go to mincoords normally
+ double sy1 = minCoords[1]; double sy2 = minCoords2[1]; double sy3 = minCoords3[1];
+ if((sy1 > y1 && sy2 > y1 && sy3 > y1) || (sy1 < y1 && sy2 < y1 && sy3 < y1) ){
+ boolean removestatus = defaultAdd(minCoords);
+ }
+ // but if they're not, then go towards the center
+ else if(Math.abs(sy1)-Math.abs(y1) < 0){ // first one is towards the center!
+ boolean removestatus = defaultAdd(minCoords);
+ if(Math.abs(sy2)-Math.abs(y1) > 0 ){
+ // then the 2nd guy is in the opposite direction, add him to next
+ nextCoords.add(minCoords2);
+ }
+ else if(Math.abs(sy3)- Math.abs(y1) > 0){
+ // then the 2nd guy is in the same direction, and the third is in the opposite
+ nextCoords.add(minCoords3);
+ }
+ }// done handling the case with the first one towards the enter
+ else if(Math.abs(sy2) - Math.abs(y1) < 0){ //second one is towards the center!
+ boolean removestatus = defaultAdd(minCoords2);
+ nextCoords.add(minCoords); // closest wasn't towards the center, so add to to-do
+ // third closest will then be eaten up in the next hit
+ }
+ else if(Math.abs(sy3) - Math.abs(y1) < 0){//third one is towards the center
+ // other two are towards the outside
+ boolean removestatus = defaultAdd(minCoords3);
+ nextCoords.add(minCoords);
+ System.out.println("Towards the center on the third closest, vert.");
+ }
+
+ }
+ if(isStraight(minCoords,minCoords2) == -1){
+ // then we're horizontal
+ double sx1 = minCoords[1]; double sx2 = minCoords2[1]; double sx3 = minCoords3[1];
+ //if they're all on the same side, go to the mincoords normally
+ if((sx1 > y1 && sx2 > y1 && sx3 > y1) || (sx1 < y1 && sx2 < y1 && sx3 < y1) ){
+ boolean removestatus = defaultAdd(minCoords);
+ }
+ // but if they're not, then go towards the center
+ else if(Math.abs(sx1)-Math.abs(y1) < 0){ // first one is towards the center!
+ boolean removestatus = defaultAdd(minCoords);
+ if(Math.abs(sx2)-Math.abs(y1) > 0 ){
+ // then the 2nd guy is in the opposite direction, add him to next
+ nextCoords.add(minCoords2);
+ }
+ else if(Math.abs(sx3)- Math.abs(y1) > 0){
+ // then the 2nd guy is in the same direction, and the third is in the opposite
+ nextCoords.add(minCoords3);
+ }
+ }// done handling the case with the first one towards the enter
+ else if(Math.abs(sx2) - Math.abs(y1) < 0){ //second one is towards the center!
+ boolean removestatus = defaultAdd(minCoords2);
+ nextCoords.add(minCoords); // closest wasn't towards the center, so add to to-do
+ // third closest will then be eaten up in the next hit
+ }
+ else if(Math.abs(sx3) - Math.abs(y1) < 0){//third one is towards the center
+ // other two are towards the outside
+ boolean removestatus = defaultAdd(minCoords3);
+ nextCoords.add(minCoords);
+ System.out.println("Towards the center on the third closest, horiz.");
+ }
+
+
+ }
+ }
+
+
+ // before doing the normal thing, just finally check if there's a closer thing on the to-do list
+ // this is if we have a really big jump coming
+ else if(minDist > BIG_CUTOFF*0.5 && nextCoords.size()>0){
+ System.out.println("in the new small jump branch");
+ // if we have a fairly large jump to go, check that there's nothing closer on the to-do list
+ Double[] removeme = nextCoords.get(nextCoords.size()-1);
+ int i = nextCoords.size()-1;
+ while(sortedCoords.contains(removeme)){
+ i--;
+ if(nextCoords.size() > 0 && i >= 0) removeme = nextCoords.get(i);
+ else{
+ removeme = null;
+ break;
+ }
+ }
+ System.out.println(i); System.out.println(removeme[1]);
+
+ if(removeme!=null){
+ double removedist = Math.pow(Math.pow(x1-removeme[0],2)+Math.pow(y1-removeme[1],2),0.5);
+ System.out.println(removedist); System.out.println(minDist);
+ if(removedist < minDist){
+ sortedCoords.add(removeme);
+
+ boolean removestatus = _coordinates.remove(removeme);
+ System.out.println("removestatus on jump: " + String.valueOf(removestatus));
+ System.out.println("jumped to short to-do-list!"+String.valueOf(minCoords2));
+ }
+ else{
+ //default stuff otherwise
+ boolean removestatus = defaultAdd(minCoords);
+ }
+ }
+ }
+
+ else{ // just do the normal thing otherwise... going to get here most of the time
+
+ //finally, the real default.
+ boolean removestatus = defaultAdd(minCoords);
+ //System.out.println("removestatus on normal: " + String.valueOf(removestatus));
+ }
+
+ //System.out.println("Size of coordinates: " + String.valueOf(_coordinates.size()) );
+
+ }
+ //Double blah[] = _coordinates.get(0);
+ //System.out.println("remaining guy is: " + String.valueOf(blah[0])+ " "+ String.valueOf(blah[1]));
+ //System.out.println("Size of nextCoords is " + nextCoords.size());
+ //System.out.println("Does nextCoords contain last dude? " + nextCoords.contains(blah));
+ return;
+ }
+
+ private boolean defaultAdd(Double[] add){
+ sortedCoords.add(add); //add resulting minCoords to sortedCoords
+ boolean removestatus = _coordinates.remove(add);
+ return removestatus;
+ }
+
+ private static double FLAT_ANGLE_CUT = 0.1;
+ private static double FLAT_XY_CUT = 100;
+
+ // returns 0 if not straight
+ // returns -1 if horizontal
+ // returns 1 if vertical
+ private int isStraight(Double[] coords1, Double[] coords2){
+ Double x1 = coords1[0];
+ Double x2 = coords2[0];
+ Double y1 = coords1[1];
+ Double y2 = coords2[1];
+ Double angle1 = coords1[2];
+ Double angle2 = coords2[2];
+
+ //double piremain1 = Math.abs(angle1)%Math.PI;
+ //double piremain2 = Math.abs(angle2)%Math.PI;
+
+ //if((piremain1 < FLAT_ANGLE_CUT || piremain1 > Math.PI-FLAT_ANGLE_CUT)
+ // && (piremain2 < FLAT_ANGLE_CUT || piremain2 > Math.PI-FLAT_ANGLE_CUT) ){
+ if(Math.abs(Math.abs(angle1)-Math.PI) < FLAT_ANGLE_CUT && Math.abs(Math.abs(angle2)-Math.PI) < FLAT_ANGLE_CUT ){
+ //both are horizontal in this case: check that they're in the same line now
+ if(Math.abs(y1-y2) < FLAT_XY_CUT){
+ // they're in the same line, and they're horizontal
+ return -1;
+ }
+ }
+ //else if(((Math.abs(angle1)%(Math.PI/2)) < FLAT_ANGLE_CUT ) && (Math.abs(angle1)%(Math.PI) > FLAT_ANGLE_CUT )
+ // && ((Math.abs(angle2)%(Math.PI/2)) < FLAT_ANGLE_CUT) && (Math.abs(angle2)%(Math.PI) > FLAT_ANGLE_CUT )){
+ else if(Math.abs(Math.abs(angle1)-Math.PI/2) < FLAT_ANGLE_CUT && Math.abs(Math.abs(angle2)-Math.PI/2) < FLAT_ANGLE_CUT){
+ // both are vertical.
+ if(Math.abs(x1-x2) < FLAT_XY_CUT){
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
public List<Double[]> getImageCoordinates() {
return _coordinates;
}