Recognize shifted streaks, testcases

This commit is contained in:
Guntram Blohm 2020-06-15 18:04:04 +02:00
parent f3419dd0f8
commit d65d05c69b
5 changed files with 71 additions and 40 deletions

View File

@ -134,7 +134,6 @@ class MatrixComparison {
}
dumpMatrix("tried to match");
/* Forget about this now; this doesn't work.
// There may still be an occasional swap, like with 0.1/0.0/0.35/0.25 above.
// On the measurements, this looks like this:
@ -143,56 +142,78 @@ class MatrixComparison {
// This may either be due to inconsistent stretching (in which case UX/VW
// should be turned into UW/VX), or one new wire break (U) and an old one
// that wasn't recognized (X). We assume it's inconsistent stretching and
// swap the matches if the rations AU/AW, UV/WX and VB/XB are close to 1.0,
// swap the matches if the rations MU/MW, UV/WX and VN/XN are close to 1.0,
// and assume it's new/old breaks if they aren't.
// Note we can also have something like
// M---------------A-B-C-D----------------N
// M-----------P-Q-R-S--------------------N
// where we get AR/BS/CQ/DP but want AP/BQ/CR/DS.
// Algorithm: find a swapped pair of x/y values. Expand left and right
// to the surrounding rectangle as long as distances are small.
// Sort the y values within.
Arrays.sort(matches);
float maxAllowedStretch = ratio(matches[matches.length-1].x, matches[matches.length-1].y)*1.1f; // allow 10% stretch
boolean foundShiftedStreaks;
do {
foundShiftedStreaks = false;
for (int i=0; i<matches.length-1; i++) {
if (matches[i].y > matches[i+1].y) { // i=B, i+1=C in above case
// find the last pair that has decrementing Y (DP)
int decrementingLength=1;
int minInvolvedY=matches[i+1].y;
while (i+decrementingLength < matches.length-1
&& matches[i].y > matches[i+decrementingLength+1].y) {
if (minInvolvedY > matches[i+decrementingLength+1].y) {
minInvolvedY = matches[i+decrementingLength+1].y;
}
decrementingLength++;
}
// here, i should index B, and decrementingLength should be 2 so i+DL indexes D
// next, count how many elements we need to go back from S to find P. As matches
// is sorted by X, and we don't have a sorted array of Y's, count how many
// Ys that are actually referenced are in [P, S] - here, 4.
int matchingYs=0;
for (int j=0; j<matches.length; j++) {
if (matches[j].y >= minInvolvedY
&& matches[j].y <= matches[i].y) {
matchingYs++;
if (matches[i].y > matches[i+1].y && xAxisVal[matches[i].x] > xAxisVal[matches[i+1].x] - 0.03) {
foundShiftedStreaks = true;
int minx = i;
int maxx = i+1;
int miny = matches[maxx].y;
int maxy = matches[minx].y;
boolean expanded;
do {
// find largest y difference between start/end spots
float deltax = 0;
for (int j=minx; j<maxx; j++) {
float thisdelta = xAxisVal[j+1]-xAxisVal[j];
if (thisdelta > deltax) {
deltax = thisdelta;
}
}
int lastChainX=i+decrementingLength; // find D
int firstChainX=i+decrementingLength+1-matchingYs; // find A
if (ratio(xAxisVal[matches[firstChainX].x]-0.0f, yAxisVal[matches[lastChainX].y]-0.0f) < maxAllowedStretch // compare MA to MP
&& ratio(xAxisVal[matches[lastChainX].x]-xAxisVal[matches[firstChainX].x], yAxisVal[matches[i].y]-yAxisVal[matches[lastChainX].y]) < maxAllowedStretch // compare AD to PS
&& ratio(1.0f-xAxisVal[matches[lastChainX].x], 1.0f-yAxisVal[matches[i].y]) < maxAllowedStretch) {
System.out.printf("I should switch between %d and %d but don't know how yet\n", firstChainX, lastChainX);
int[] resorted = new int[lastChainX-firstChainX+1];
// switch: AR BS CQ DP to AP BQ CR DS
} else {
// remove match CQ, DP
for (int j=1; j<=decrementingLength; j++) {
matches[i+j].x=matches[i+j].y=-1;
// and allow 1.5 times this for the rest
deltax = deltax * 3 / 2;
// but only 3% of the whole length
if (deltax > 0.03f) {
deltax = 0.03f;
}
System.out.println("shifted streak found from "+minx+" to "+maxx+", miny="+miny+", maxy="+maxy+", maximum x delta is "+deltax);
expanded = false;
// expand right
while (maxx < matches.length-1 && matches[maxx+1].y < maxy && xAxisVal[maxx+1] < xAxisVal[maxx]+deltax) {
maxx++;
expanded = true;
if (miny > matches[maxx].y) {
miny = matches[maxx].y;
}
}
i+=decrementingLength; // so it starts after current stretch on next iteration
// expand left
while (minx > 0 && matches[minx-1].y > miny && xAxisVal[minx-1] > xAxisVal[minx]-deltax) {
minx--;
expanded = true;
if (maxy < matches[minx].y) {
maxy = matches[minx].y;
}
}
*/
} while (expanded);
System.out.println("expansions ended");
// As the X values are sorted anyway, sort the Y values as well, and assign them to the X values in order
int[] sortedY = new int[maxx-minx+1];
for (int j=0; j<maxx-minx+1; j++) {
sortedY[j] = matches[j+minx].y;
}
Arrays.sort(sortedY);
for (int j=0; j<maxx-minx+1; j++) {
matches[j+minx].y = sortedY[j];
}
dumpMatrix("after resolving a streak");
break /* the inner loop only */;
}
}
} while (foundShiftedStreaks);
Arrays.sort(matches);
for (int i=0; i<matches.length-1; i++) {

View File

@ -0,0 +1,5 @@
splice begin 0 100 100 100 50 1 0 1
wire break 1 120 120 120 50 0 -1 0
wire break 2 320 320 320 50 0 -1 0
splice end 3 500 500 500 50 0 -1 0
splice begin 4 1000 1000 1000 50 1 0 1
1 splice begin 0 100 100 100 50 1 0 1
2 wire break 1 120 120 120 50 0 -1 0
3 wire break 2 320 320 320 50 0 -1 0
4 splice end 3 500 500 500 50 0 -1 0
5 splice begin 4 1000 1000 1000 50 1 0 1

View File

@ -0,0 +1,5 @@
splice begin 0 100 100 100 50 1 0 1
wire break 1 280 280 280 50 0 -1 0
wire break 2 480 480 480 50 0 -1 0
splice end 3 500 500 500 50 0 -1 0
splice begin 4 1000 1000 1000 50 1 0 1
1 splice begin 0 100 100 100 50 1 0 1
2 wire break 1 280 280 280 50 0 -1 0
3 wire break 2 480 480 480 50 0 -1 0
4 splice end 3 500 500 500 50 0 -1 0
5 splice begin 4 1000 1000 1000 50 1 0 1

Binary file not shown.

Binary file not shown.