Rectangle in a grid - I need help on the edge cases - math

The problem I'm trying to solve is the following:
In a 2-D space, Given a grid size and a rectangle, calculate the grid cells
occupied (partially or totally) by the rectangle.
By "Grid size" I mean something like: "A 16x16 grid" or "A 32x32 grid". All grids are centered on the origin of coordinates (0,0).
The rectangle is defined by 4 floats: the left, top, width and height.
The result of this operation is always a rectangle. I'd like to return the coordinates of top-left cell (i.e. 0,0) followed by the number of cells the retangle occupies to the right and down (a bit like width and height, but for cells)
So far I've been able to write an algorithm that mostly works. What it does first, is calculating the cell coordinates where a single dot resides in the grid. Then, given the rectangle, I calculate where its top-left and lower-rights corner are on the grid, and then it's a simple substraction:
-- given a world coordinate, return the coordinates of the cell that would contain it
local function _toGrid(wx, wy)
return math.floor(wx / __cellSize), math.floor(wy / __cellSize)
end
-- given a box in world coordinates, return a box in grid coordinates that contains it
-- returns the x,y coordinates of the top-left cell, the number of cells to the right and the number of cells down.
local function _toGridBox(l, t, w, h)
local gl,gt = _toGrid(l, t) -- top left grid corner
local gr,gb = _toGrid(l+w, t+h) -- bottom-right grid corner
return gl, gt, gr-gl+1, gb-gt+1 -- return top,left,cells to the right, cells to bottom
end
Notes:
The source code is Lua, but I will accept solutions in any programming language, as long as they are intelligible.
The y-coordinate goes "down when increasing"; that's how a lot of screen systems work. I don't think that's significant for this problem, but don't get confused by that).
In a 16x16 grid, a rectangle on 0,0, with width=10 and height=20, gr will be 0 and gt 1, so _toGrid will return 0,0,1,2 (1 row, two columns, on the 0,0 cell).
The problem happens when the rectangle "touches" (not crosses) either the lower or right side of one cell from inside. In that case, _toGrid returns "one more cell" than I'd like it to.
For example, if I move the previous rectangle to the left 6 pixels (so it is on 10,0), it will be "touching" the left-side border of its containing grid, which goes from 0 to 16. Then gr will be 1, and the returned data will be 0,0,2,2.
I'd like to avoid this, if at all possible. For a rectangle going to 16 "from the left", I'd like it to remain on the first grid cell. I'd like it to begin "occupying the next cell" as soon as it surpasses 16 - for example when it's at 16.00000001 .
Also, notice that this only applies to the right and bottom sides. The left and upper sides work as I want them to. For example, a rectangle whose left coordinate is 16, should appear on the "second cell to the right", not on the first.
I'm sure the solution isn't complicated, but I've been thinking about this for a while now and I don't seem to find it. Any help will be appreciated.

For the bottom and right hand side, you need to use ceil instead of floor. I don't know any Lua, so this may not be syntactically correct, but you would want something along these lines:
local function _toGridBox(l, t, w, h)
local gl = math.floor(l / _cellSize)
local gt = math.floor(t / _cellSize)
local gr = math.ceil((l+w) / _cellSize)
local gb = math.ceil((t+h) / _cellSize)
return gl, gt, gr-gl, gb-gt -- return top,left,cells to the right, cells to bottom
end
Your problem, essentially, is that the function _toGrid is the wrong abstraction for your purpose because it always uses floor. Apparently, you locked yourself into using that abstraction, which then made it difficult to come up with the right answer.

Related

Find center of a fixed-width bounding box

Given a collection of points, I'd like to find the center of a bounding box (fixed-length and width) that maximizes the number of points within said box. I'm at a loss for an efficient way to do this.
Algorithm with complexity O(N^2*logN) (I hope that better one exists):
Edit: article exploiting interval trees claims O(NlogN) complexity
Sort data array A by X coordinate.
Scan A with sweep line left to right.
For every point in A get LeftX = A[k].X - left coordinate of vertical band, find the rightmost coordinate of vertical band RightX = LeftX + Width.
Copy points inside the band to another array B.
Sort B by Y-coordinate.
Scan B width sweep line top to down.
For every point B[i] get TopY = B[i].Y - top coordinate of rectangle, calculate BottomY = TopY + Height.
Use binary search in B:
B[j] is the last bottom point in B with B[j].Y <= BottomY.
Find number of points in the current rectangle:
Number of points is N(k, i) = j - i + 1
Check whether N(k, i) is maximum among others
This seems like a difficult problem, here is my idea:
Hold a graph, each node holds a rectangle and a subset of points. the rectangle defines the area where placing the bounding box in would overlap all the points in the subset.
To build the graph:
Start with a root node holding the empty set and the rect [top:-inf, bottom:inf, left:-inf, right:inf]
For each point in the tree call this recursive function with the root node (pseudo code):
function addPoint(node, point)
// check that you didn't already try to add this point to this node
// node.tested can be a hash set
if(node.tested contains point)
return
node.tested.add(point)
newRect = node.rect.intersectWith(boundingBoxAround(point))
// if the bounding box around the point does not intersect the rectangle, return
if(newRect is invalid) // rect is invalid if right<left or bottom<top
return
node.addChild(new node(newRect, node.pointSet U {point})
for each child of node
addPoint(child, point)
Now you just pick the node with the largest subset, you can keep track of that when building the graph so you don't need to run through the graph again.
I hope my idea is clear, let me know if I can explain it better.

Extract pixel coordinates in scilab

I have extracted edge using image processing then I selected pixel coordinate using xclick of extracted edge.Is this correct or there is need of reverse y axis coordinate?(Extracted edge is white on black background)
I want to automatically extracted pixel coordinates of extracted edge not by mouse selection.Is there is any command available in scilab?(I use canny edge detector and morphological filter to extract edge)
Please give me some suggestions
Thanks
1.) Whether to reverse the y coordinte or not, depends on the further processing. Any coordinate system can be used if you need only relative measurements and the true orientation of your features is not important (e.g. reversing top and bottom makes no difference if you simply want to count objects or droplets). Hovewer if you want to indicate your found features by plotting a dot, or a line, or a rectangle (e.g. with plot2d or xrect) or a number (e.g. with xnumb) over the image, then it's necessary to match the two coordinate sytems. I recommend this second option and to plot your result over the original image, since this is the easiest way to check your results.
2.) Automatic coordinate extraction can be made by the find function: it returns those indices of the matrix, where the expression is true.
IM=[0,0,0,1;0,0,0,1;0,1,1,1;1,1,0,0]; //edge image, edge = 1, background = 0
disp(IM,"Edge image");
[row,col]=find(IM==1); //row & column indices where IM = 1 (= edge)
disp([row',col'],"Egde coordinates (row, col)");
If your "Egde image" marks the edges not with 1 (or 255, pure white pixel) but with a relatively high number (bright pixel), then you can modify the logical expression of the find function to detect pixels with a value above a certain threshold:
[row,col]=find(IM>0.8); //if edges > a certain threshold, e.g. 0.8
EDIT: For your specific image:
Try the following code:
imagefile="d:\Attila\PROJECTS\Scilab\Stackoverflow\MORPHOLOGICAL_FILTERING.jpg";
//you have to modify this path!
I=imread(imagefile);
IM=imcrop(I,[170,100,950,370]); //discard the thick white border of the image
scf(0); clf(0);
ShowImage(IM,'cropped image');
threshold=100; //try different values between 0-255 (black - white)
[row,col]=find(IM>threshold);
imheight=size(IM,"r"); //image height
row=imheight-row+1; //reverse y axes coordinates (0 is at top)
plot2d(col,row,style=0); //plot over the image (zoom to see the dots)
scf(1); clf(1); //plot separate graph
plot2d(col,row,style=0);
If you play with the threshold parameter, you will see how the darker or whiter pixels are found.

determine rectangle rotation point

I would like to know how to compute rotation components of a rectangle in space according to four given points in a projection plane.
Hard to depict in a single sentence, thus I explain my needs.
I have a 3D world viewed from a static camera (located in <0,0,0>).
I have a known rectangular shape (an picture, actually) That I want to place in that space.
I only can define points (up to four) in a spherical/rectangular referencial (camera looking at <0°,0°> (sph) or <0,0,1000> (rect)).
I considere the given polygon to be my rectangle shape rotated (rX,rY,rZ). 3 points are supposed to be enough, 4 points should be too constraintfull. I'm not sure for now.
I want to determine rX, rY and rZ, the rectangle rotation about its center.
--- My first attempt at solving this constrint problem was to fix the first point: given spherical coordinates, I "project" this point onto a camera-facing plane at z=1000. Quite easy, this give me a point.
Then, the second point is considered to be on the <0,0,0>- segment, which is about an infinity of solution ; but I fix this by knowing the width(w) and height(h) of my rectangle: I then get two solutions for my second point ; one is "in front" of the first point, and the other is "far away"... I now have a edge of my rectangle. Two, in fact.
And from there, I don't know what to do. If in the end I have my four points, I don't have a clue about how to calculate the rotation equivalency...
It's hard to be lost in Mathematics...
To get an idea of the goal of all this: I make photospheres and I want to "insert" in them images. For instance, I got on my photo a TV screen, and I want to place a picture in the screen. I know my screen size (or I can guess it), I know the size of the image I want to place in (actually, it has the same aspect ratio), and I know the four screen corner positions in my space (spherical or euclidian). My software allow my to place an image in the scene and to rotate it as I want. I can zoom it (to give the feeling of depth)... I then can do all this manually, but it is a long try-fail process and never exact. I would like then to be able to type in the screen corner positions, and get the final image place and rotation attributes in a click...
The question in pictures:
Images presenting steps of the problem
Note that on the page, I present actual images of my app. I mean I had to manually rotate and scale the picture to get it fits the screen but it is not a photoshop. The parameters found are:
Scale: 0.86362
rX = 18.9375
rY = -12.5875
rZ = -0.105881
center position: <-9.55, 18.76, 1000>
Note: Rotation is not enought to set the picture up: we need scale and translation. I assume the scale can be found once a first edge is fixed (first two points help determining two solutions as initial constraints, and because I then know edge length and picture width and height, I can deduce scale. But the software is kind and allow me to modify picture width and height: thus the constraint is just to be sure the four points are descripbing a rectangle in space, with is simple to check with vectors. Here, the problem seems to place the fourth point as a valid rectangle corner, and then deduce rotation from that rectangle. About translation, it is the center (diagonal cross) of the points once fixed.

How do I find the dimensions of a rotated rectangle within an unrotated rectangle such that area is maximized?

I have a rectangle that is W x H.
Within that rectangle is another rectangle that is rotated by ϴ degrees which is always between -45 and 45 degrees, and shares the same center as the outer rectangle. I need to find w and h such that the area of the inner rectangle is maximized.
Here's a (ghetto) image to illustrate a bit. Though, the corners of the rectangles should probably be touching, I assume?
Here is the prototype of the function I'm looking to write:
SizeD GetMaxRectangleSize(double outerWidth, double outerHeight, float angle)
SizeD is just a struct that has a width and height in doubles.
Thanks to the comments for steering me in the right direction!
My solution, though perhaps not mathematically optimal, was to assume that if all four corners of the inner rectangle fall on the outer rectangle then area will be maximized.
Therefore:
H = wSin(ϴ) + hCos(ϴ)
W = wCos(ϴ) + hSin(ϴ)
Solving for w and h and substituting gives:
h = (HCos(ϴ) - WSin(ϴ))/(cos(ϴ)^2 - sin(ϴ)^2)
w = (WCos(ϴ) - HSin(ϴ))/(cos(ϴ)^2 - sin(ϴ)^2)
Which happens to work for ϴ = [0,45), and (-45,0] should act the same.
The tricky part of this question isn't how to calculate the area of an interior rectangle, but which of all the possible interior rectangles has maximum area?
To start with, observe that the box in your image is the same area regardless of how it is slid around horizontally, and if it is slid to the rightmost wall, it allows for an easy parameterization of the problem as follows:
I find it a bit easier to think of this problem, with the fixed box rotated by the offset angle so that the interior box lines up in a standard orientation. Here's a figure (I've changed theta to beta just because I can type it easily on a mac, and also left off the left most wall for reasons that will be clear):
So think of this constructed as follows: Pick a point on the right side of the exterior rectangle (shown here by a small circle), note the distance a from this point to the corner, and construct the largest possible interior with a corner at this point (by extending vertical and horizontal lines to the exterior rectangle). Clearly, then, the largest possible rectangle is one of the rectangles derived from the different values for a, and a is a good parameter for this problem.
So given that, then the area of the interior rectangle is:
A = (a * (H-a))/(cosß * sinß)
or, A = c * a * (H-a)
where I've folded the constant trig terms into the constant c. We need to maximize this, and to do that the derivative is useful:
dA/da = c * (H - 2a)
That is, starting at a=0 (ie, the circle in the figure is in the lower corner of the exterior rectangle, resulting in a tall and super skin interior rectangle), then the area of the interior rectangle increases monotonically until a=H/2, and then the area starts to decrease again.
That is, there are two cases:
1) If, as a increase from 0 to H/2, the far interior corner hits the opposite wall of the exterior, then the largest possible rectangle is when this contact occurs (and you know it's the largest due to the monotonic increase -- ie, the positive value of the derivative). This is your guess at the solution.
2) If the far corner never touches a wall, then the largest interior rectangle will be at a=H/2.
I haven't explicitly solved here for the area of the interior rectangle for each case, since that's a much easier problem than the proof, and anyone who could follow the proof, I assume could easily calculate the areas (and it does take a long time to write these things up).

2D Array traversal from corner to center

In a given 2D square (n*n) even size array, i want to traverse from a starting corner till its center. Below is the image for more info.
My algorithm is to start from corner and maintain two global variable as currentX and currentY and run a loop until currentX and currentY reach to the center. Below is my pseudo code-
x=0
y=0
currentX=0
currentY=0
while(currentX != centerX and currentY != centerY){
currentX=travel_in_x_plus_direction(x,n);
currenty=travel_in_y_plus_direction(y,n);
currentX=travel_in_x_minux_direction(currentX,x);
currentY=travel_in_y_minux_direction(currentY,y-1);
n--;
x--;
y--;
}
The function travel_in_x_plus_direction(currentX) traverse the array starting from currentX till x and returns the final value of x. The same concept applies for rest of the functions also.
Is this the right way? Is there any better way to traverse it in the same manner?
Psuedocode "uses the structural conventions of a programming language, but is intended for human reading rather than machine reading." (http://en.wikipedia.org/wiki/Pseudocode)
I would suggest that writing psuedocode that conforms to this definition would be of great benefit to you and help you think about how you are going about solving your problem.
Your algorithm
Seems to suggest that you are
checking if you are at your goal "END", and if you are not
Move right
Move down
Move left
Move up
which means you will never get anywhere.
Starting point for a solution
My container is of size n*n
therefore intially the boundary is n*n
if I travel through an individual square, it becomes part of the boundary.
The path is quite simple, begin by moving right, and then whenever blocked change direction. The sequence of directions is right, down, left, up in that order, until the goal is reached.
HorizontalMax = n (the right wall)
HorizontalMin = 0 (the left wall)
VerticalMax = n (the bottom wall)
VerticalMin = 0 (the top wall)
While not at goal
While not at right boundary or goal
Move right
Increment VerticalMin (you just moved along the top wall)
While not at bottom boundary or goal
Move down
Decrement HorizontalMax (you just moved along the right wall)
While not at left boundary or goal
Move left
Decrement VerticalMax (you just moved along the bottom wall)
While not at top boundary or goal
Move up
Increment HorizontalMin (you just moved along the left wall)
End

Resources