Hi all,
I did not have to deal with math for a very long time. Now I have a hard time finding an elegant solution for the following problem:
When I build a map procedurally, there is a mechanism that makes sure all the work is done only once for each mirrored pixel.
A method forEachPixelToUpdate(streamSource, scope, action, map, mirrorMode, mirrorLine) can be used for that.
The actions that modify the map on a pixel basis can work with the following parameters
action.apply(scope, [ streamSource, map, indexX, indexY,
mirrorIndexX, mirrorIndexY, maxValue, minValue,
neighborTopLeft, neighborTopCenter, neighborTopRight,
neighborLeft, neighborRight, neighborBottomLeft,
neighborBottomCenter, neighborBottomRight ]); Now the implementation of forEachPixelToUpdate is not quite correct.
The mechanism that determines if a position indexX / indexY is in the mirrored area for point symmetry is causing headaches.
Basically I draw a line through the map and want to continue with the next map row as soon as the line is reached.
The line is created from a pseudo random mirrorLine number that lies between 0 and (maxIndexX + maxIndexY).
var line = new Object();
if (mirrorLine > maxIndexY) {
var offsetX = mirrorLine - maxIndexY;
line.point1X = offsetX;
line.point1Y = 0;
line.point2X = maxIndexX - offsetX;
line.point2Y = maxIndexY;
} else {
line.point1X = 0;
line.point1Y = mirrorLine;
line.point2X = maxIndexX;
line.point2Y = maxIndexY - mirrorLine;
} I continue in the special cases that:
- indexY is smaller than both line.point1Y and line.point2Y
- or indexX is smaller than both line.point1X and line.point2X
For the other cases all I could think of was implementing complete linear function check implementations for both cases:
- point1X = 0 (The line crosses the left and right sides)
- point1Y = 0 (The line crosses the top and bottom sides)
At that point I got the feeling that the algorithm was getting too complex. There are probably implicit facts that can be used to simplify it.
If there are none, then probably using vectors and determining which side the index is on will probably be simpler than using a linear function.
I do not really know how to do either, though. I probably can, given enough time, but it is taking forever to make progress.
Any suggestions? This is the relevant code in forEachPixelToUpdate ()
vertical: for (indexY = 0; indexY <= maxIndexY; indexY++) {
if (MIRRORMODE_POINT == mirrorMode) {
if ((indexY < line.point1Y) && (indexY < line.point2Y)) {
continue;
} else if (0 == line.point1Y) {
// Linear function to determine if we are in the mirrored area
var diff = line.pointX2 - line.pointX1;
var slope = ?;
var offset = ?; // ...
// How do I do it?
}
}
indexTop = indexY - 1;
indexBottom = indexY + 1;
if (0 > indexTop) {
indexTop = maxIndexY;
} else if (maxIndexY < indexBottom) {
indexBottom = 0;
}
horizontal: for (indexX = 0; indexX <= maxIndexX; indexX++) {
if (MIRRORMODE_AXIS == mirrorMode) {
if (0 == mirrorLine) {
if (indexY > ((mapArray.length / 2) - 1)) {
break; // does break vertical work here?
} else {
mirrorIndexX = indexX;
mirrorIndexY = maxIndexY - indexY;
}
} else if (1 == mirrorLine) {
if (indexX > ((mapArray[indexY].length / 2) - 1)) {
continue vertical;
} else {
mirrorIndexX = maxIndexX - indexX;
mirrorIndexY = indexY;
}
} else if (2 == mirrorLine) {
if (indexX > indexY) {
continue vertical;
} else {
mirrorIndexX = indexY;
mirrorIndexY = indexX;
}
} else if (3 == mirrorLine) {
if (indexX > ((mapArray.length - indexY) - 1)) {
continue vertical;
} else {
mirrorIndexX = maxIndexY - indexY;
mirrorIndexY = maxIndexX - indexX;
}
}
} else {
if ((indexX < line.point1X) && (indexX < line.point2X)) {
continue horizontal;
} else if (0 == line.point1X) {
// Linear function to determine if we are in the mirrored area
var diff = line.pointY2 - line.pointY1;
var slope = ?; // ...
var offset = ?; // ...
// How do I do it?
}
mirrorIndexX = maxIndexY - indexX;
mirrorIndexY = maxIndexX - indexY;
}