Grid image values to 2D array - arrays

I have a grid like the image below which I want to put in an array in this format:
;x = wall(black cells and grey boxes), s= start (red circle), g = goal(blue circle), 0 = available path(everything else)
$data[5][5] = [["x","x","x","x","x"], _
["x","s","0","x","x"], _
["x","x","0","x","x"], _
["x","x","0","g","x"], _
["x","x","x","x","x"]]
I thought I could use the colors but I'm not sure how.

looks like you have the view with fixed angles
create function that converts screen position to grid position and back. It should be easy just 2x linear interpolation. if the camera pan is not with cell based step then you need the corner point of grid lines and use that as a start point ...
for example something like this (hope I measured the pixels correctly):
x = 236 + (+(u-uh)-(v-vh))*60;
y = 133 + (-(u-uh)-(v-vh))*30;
60,30is the cell size in x,y
(236,133) is position of center of mid cell (uh,vh) in pixels
uh,vh are coordinates in your grid of center cell
add the views pan offset to (uv,hv) or (236,133) now just compute the also the reverse transform from this (u=?,v=?). Do not forget that the map is not rectangle! It is something like this:
0000x0000,
000xxx000,
00xxxxx00,
0xxxxxxx0,
xxxxxxxxx,
0xxxxxxx0,
00xxxxx00,
000xxx000,
0000x0000,
create a set of images of all objects that you can encounter
this can be done on the run, each time you do not found a match add cell to item list as new object type.
loop through all grid cell locations and compare to object types
for pixel precise rendered images you can compare directly pixels 1:1 if that is not the case the you need to compare objects more robustly. But to make a valid algorithm we need to see all the types of object you can encounter usually you can compare:
average,min and max colors, histograms,
aspect ratio,...
FFT/DCT
center of mass position,density, and more
do not forget to mask comparison to area of cell only to not include the neighboring cells on corners of bounding rectangle
[Notes]
Can not be more specific without further info

Related

Discover that a filled-in grid has a circle; fill in the area

Hi, I'm currently in the middle of a project where a new grid is added on to a chain of blocks on the grid every timestep. How would I be able to detect that a circle has been made in the grid? Given that all I have are the coordinates (x,y) and the color of each cell. By "circle" I mean an area that is sealed off, as shown in the picture.
Thanks in advance! By the way, I'm not asking how to click on a cell and apply the flood-fill algorithm.
The aftermath of the algorithm should produce this:
You need to split all of your white (unfilled) squares into sets of squares adjacent to each other. Start with any white square, add all of its unfilled adjacent squares to the set, and keep doing it until you've included all of the squares.
Once you have those sets, you will have a "circle" (as you named it) if there are non-empty sets that do not contain any border squares. Then to fill these sets you just change the color of each member to blue.
If you have the sets from the previous step, when you add another brick you just need to consider the set that included the affected square to see if it has been split into two sets and whether either of these new sets may be a "circle".

How to draw a rectangle in a cell throught relative position of it within the cell that contains it?

I have the property RelativePosition in class MapItem is the relative position of the working point within the cell that contains it. The two components of the vector are always in the range [0,1]. In our example image below the corrdinates would be something like (0.25, 0.05).
Each item has a property RelativePosition which is a Vector that defines the working point position relative to the item. For example (0,0) is the top-left corner and (1,1) is the bottom-right.
How to draw a rectangle in a cell throught relative position ? Thanks for help me?
Have you thought about positioning the image by using containers? Maybe UniformGrid could fit for you. If you want the middle of the image at 0.25 from the left center it in the left cell of an UniformGrid with two columns.

I want to have a set of patches overlay onto an image and want to control their color range?

I have a set of patches I am overlaying onto an image. The below patches draw a grid of boxes over the image. This works when I dont try and restrict the colormap range. But when I try and set it with caxis it does not allow me to use the array of hpatch as a handle. How can I get this to work? or is there a better approach then what I am doing? Also the image is grayscale but I would like the patches to use the jet colormap. Is this possible to do?
hFig = figure;
hAx = axes('Parent',hFig);
for i = 1:256
hpatch(i) = patch([x2(i+17) x2(i+18) x2(i+1) x2(i)],[y2(i+17) y2(i+18) y2(i+1) y2(i)],[0 0 0 0],'Parent',hAx, 'FaceColor','flat','CData',cdata(i),'CDataMapping','scaled', 'FaceAlpha',(0.5));
end
caxis(hpatch,[0 25])
Here's one problem: the colormap is a figure-level property. When using the CAXIS function, you have to pass it an axes handle, not a patch handle, and specify a range that determines how the color data values in that set of axes are mapped to the colormap.
If your axes have an indexed-color image or other objects with their 'CDataMapping' property set to 'direct' or 'scaled', then it may get quite messy trying to make one colormap to accommodate them all. You would have to concatenate their colormaps into one to use for the figure, then adjust their color value indices accordingly. Changing the scaling for any one object would be more involved than just using CAXIS: you'd have to modify the corresponding section of the colormap for that object or modify its colormap indices stored in the 'CData' property.
However, you can simplify the problem by making sure only one object (or related set of objects) uses the colormap, setting all the other objects to use fixed RGB values for their 'CData'. Since you mention that your image is grayscale, it would be best to make it a Truecolor (i.e. RGB) image (if it isn't already) so that only your patches use the colormap. Here's how you can convert your image:
If the image you're plotting is an M-by-N-by-3 matrix, it's already an RGB image.
If the image is an M-by-N matrix and has an associated colormap, use the IND2RGB function to convert it to an RGB image.
If the image is an M-by-N matrix with no colormap, then IMSHOW will still display it using the figure colormap. To convert it to an RGB image, first apply whatever windowing you want to the 2-D image data, then replicate the data in the third dimension to make it an M-by-N-by-3 matrix. Here's an example (assuming img is your image data):
limits = [0.05 0.4]; %# The window you want to apply to the data
img = (img-limits(1))./diff(limits); %# Scale the data
img(img < 0) = 0; %# Clip the data outside 0 and 1 (even without these two
img(img > 1) = 1; %# steps, IMSHOW should display the data properly)
img = repmat(img,[1 1 3]); %# Replicate the image so it is 3-D
imshow(img); %# Display the image
Once you've converted and plotted the image and plotted your patches as above, you should be able to use a jet colormap for the patches like so:
colormap(jet);
caxis(hAx,[0 25]);

Possible to give fixed angle in path?

I have a path as shown in the attached image. i would like to know if it is possible to give a fixed angle for the edge of the path, coz i would like to use the same angle while styling other controls as well. Is there a way to make this possible (in Expression Blend)?
You can do this using 'Subtract' Path Operation.
1) First draw the required shapes like
2) Draw a small rectangle and rotate it to a certain angle you want. Say 50. Then, place the small rotated rectangle over the shapes draw previously, like
3) Bring each of the Big Shapes to the front, like
4) Finally, goto "Object -> Combine -> Subtract" by selecting each big and small rectangle pair. The final output will have same angle, like

simple plot algorithm with autoscale

I need to implement a simple plotting component in C#(WPF to be more precise). What i have is a collection of data samples containing time (X axis) and a value (both double types).
I have a drawing canvas of a fixed size (Width x Height) and a DrawLine method/function that can draw on it. The problem I am facing now is how do I draw the plot so that it is autoscaled? In other words how do I map the samples I have to actual pixels on my Width x Height canvas?
One hacky method that may work is to use a Viewbox control. This control will scale the rendering of its content to fit the size available. However, this might lead to your lines and labels looking too thick or thin.
The more sensible method that you're probably after, though, is how to work out at what scale to draw your graph at in the first place. To do that, work out the range of values on a given axis (for example, your Y-axis value might range from 0 to 100). Work out the available drawing space on that axis (for example, your canvas might have 400 pixels of height). Your Y-axis "scale factor" when drawing the graph would be <available space> / <data range> - or, in this case, 4.
Your canvas' coordinates start from zero in the top-left so, to calculate the Y-position for a given data point, you would calculate like this:
double availableSpace = 400.0; // the size of your canvas
double dataRange = 100.0; // the range of your values
double scaleFactor = availableSpace / dataRange;
double currentValue = 42.0; // the value we're trying to plot
double plottableY = availableSpace - (currentValue * scaleFactor); // the position on screen to draw at
The value of plottableY is the y-coordinate that you would use to draw this point on the canvas.
(Obviously this code would need to be spread out across your drawing method so you're not recalculating all of the values for each point, but it demonstrates the math).

Resources