I need to find what column and row the mouse location is in. To simplify this question, lets only find the column. I will write in pseudocode.
I have a map (a grid of rows and columns, made up by square cells) with a pixel width. I have a cell size which makes up each columns pixel width.
eg map.width / cell size = map.NumberOfColumns.
From this we can get what column the mouse is on.
Eg if ( mouse.X > cellSize ) {col is definitely > 1} (i have not used zero indexing in this example).
So if anyone here loves maths, i would very much appreciate some help. Thanks.
Assuming square cells, 1-based row/col indexing, and truncating integer division:
col = mouse.X / cellSize + 1;
row = mouse.Y / cellSize + 1;
Related
Summary: I have an array of 10 rows and 4 columns filled with numbers. I select one number from each row and want to avoid duplicates in the selection.
Elaborate:
I have a grid of 100*100 cells. In that grid are 10 cells that contain a "person". In an iterative process I want to make the persons "walk around" in the grid, but I do not want to occur that two persons are in the same cell at the same time.
I have a vector that describes the positions of the 10 persons. It contains the cell numbers with a person. These positions are counting across all rows and columns (i.e. ranges from 1:10000). For example: Position 234 would be in the 3rd row, 34th column).
Positions<-sample(1:10000,10) #Initial positions
What I did is to first make an array of the surrounding cells of each person (up, right, down, left) giving 4 positions for each person:
Surroundings<-array(c(Positions+100,Positions+1,Positions-100,Positions-1),dim=c(10,4))
I then take a random direction from each of the rows in Surroundings into vector PosNew. It is this last vector in which I want to avoid duplicates.
I could repeat the random selection process of PosNew until it has no duplicates, but this could take very long. There are probably more efficient ways to do this.
For simplicity sake, let's assume that persons do not walk off the grid and no other errors occur.
My script:
Positions<-sample(1:10000,10) #Initial positions
for(i in 1:50) {
Surroundings<-array(c(Positions+100,Positions+1,Positions-100,Positions-1),dim=c(10,4))
PosNew<-Surroundings[cbind(1:10,sample(1:4,10,replace=TRUE))]
Dups<-length(which(duplicated(PosNew)==TRUE))
Positions<-PosNew
}
I am looking for a way to check for duplicates in the selected new positions and make sure that Dups is never above zero. Any suggestions are welcome, including suggestions to make the code faster/more efficient.
Added: What could I do when at some point one or more of the persons really cannot move to an empty cell, because all 4 sides are occupied? I want that person to stay in its original cell. How to code that?
Thank you so much for your time!
As this is an iterative process, where every person's move depends on the locations of others, I don't think you can do much better then moving one person and sampling the position for the next from the difference of the sets of all directions and all occupied positions (note that this adds a bit of unfairness as the first person has the most freedom to move, so to speak).
So the code would be something like this:
Positions <- sample(1:10000, 10) #Initial positions
for (i in 1:50) {
Surroundings <-
array(c(Positions + 100, Positions + 1, Positions - 100, Positions - 1),
dim = c(10, 4))
# BEGIN NEW CODE
PosNew <- numeric(10)
for (i in 1:10) {
# PosNew[seq_len(i-1)] is the set of occupied positions
available <- setdiff(Surroundings[i, ], PosNew[seq_len(i-1)])
if (length(available) != 0)
PosNew[i] <- sample(available, 1)
else
PosNew[i] <- Positions[i] # stay where you are
}
# END NEW CODE
Dups <- sum(duplicated(PosNew)) # shorter version - sum logical values to get a count
Positions <- PosNew
}
Hope this helps!
I have an image of columns of red and blue bordered circles like so:
Where the columns alternate red and blue (in this example the first column is red)
I have been able to create a raster brick and plot the image in RGB layers but I want to count these columns into a vector like this (from above example). Values 1(red) and 2(blue)
1,1,1,1,2,2,2,1,1,2,1,1,1 ...
Is it possible to clear out areas of the brick I don't need for counting and collapse the brick down into values I could then convert into the numbers or labels I want? Or is there a much simpler way that I'm unable to locate? Also long term I want to be able to point the program at several images without opening them myself.
Edit: To clear somethings up, I want to count the circles top to bottom, left to right. For example once the first col is counted, I want to start over at the top of the next column on the right. Also I'm not sure if I'm headed in the right direction but I was able to remove all background cells from the image. leaving me with a plot of only values where the circles are.
Edit 2:
The current code I have for the image above.
color.image <- brick("image")
color.image = dropLayer(color.image,4) #gets rid of a channel
plot(color.image)
e <- extent(-10, 240, 45, 84.8) #xmin,xmax, ymin,ymax
ccolor.image <- crop(color.image, e)
plot(ccolor.image)
#thresholding to simplify what I was dealing with
mini=ccolor.image[ccolor.image > 97] = NA
mini=ccolor.image[ccolor.image < 15] = NA
mini=ccolor.image[ccolor.image > 20] = 80
plot(ccolor.image)
mcolor = as.matrix(ccolor.image)
colSums(ccolor.image)
rowSums(ccolor.image)
Edit 3:
I figured it out! Or at least found a round about way to do it, will post code later once I clean it up some. I still however would like input on creating a vector based on the matrix of values I have for my simplified raster brick matrix. Code coming soon!
The fastest way to count values in a raster is freq(x, merge=T). This will give you the value in one column and the frequency in as many columns as you have rows. In this way we the need to poll a value of interest and sum all the other columns (the counts). Hope that helps!
freq_vals <- freq ( rasterbrick , merge = T )
sum( freq_vals [ which ( freq_vals$value == 1 ) , 2 : ncol ( freq_vals ) ] )
I have to split the screen equally (as possible) given a dynamic number of items.
So i need to find the number of columns and rows based on the screen size/ratio.
Each item size is not important since i will calculate them in % based in the items per col and row.
If i have 5 items, then (depending on the screen ratio) i will probably have 3 columns in the 1st row and 2 columns in the 2nd row. That's ok.
First you have to decide what you mean with "divide the screen equally".
It probably means that there is a preferred x-to-y ratio for each item.
You could use the following algorithm that favors getting close to the desired x-to-y ratio over reducing the number of empty spaces.
// Set this to the desired x-to-y ratio.
const preferred_ratio = 1.2;
function calc_cols_rows(In: screen, In: num_items, Out: num_rows, Out: num_cols) {
desired_aspect = (screen.width / screen.height) / preferred_ratio;
// Calculate the number of rows that is closest to the desired aspect:
num_rows = round(sqrt(num_items / desired_aspect));
// Calculate the required number of columns:
num_cols = ceil(num_items / num_rows);
}
How can you get the index (counting from top-left) of an item on a grid given the (x,y) location?
NUM_COLS*x + y;
Where NUM_COLS is the number of columns in the grid.
Ok here's what I'm trying to accomplish. Say I have 100 items. I want to create a "grid"(each Item consisting of an x, y point). I want the grid to be as close to a square as possible.
Is there any kind of math to determine the grid width, and grid height i'd need by just a single number?(By grid width and height I mean the number of x items, and the number of Y items)
Now that I think about it would it be efficient to take the square root of the number, say varI=sqrt(45), remove the decimal place from varI...X=varI...then Y would be varI+1?
The square root is precisely what you need.
N
x=floor(sqrt(N))
y=raise(N/x)
This is the minimum rectangle that has more than N places and is closest to a square.
Now... if you want to find a rectangle that has exactly N places and is closest to a square...that's a different problem.
You need to find a factor of N, x, that's closest
You have to run through the factors of N and find the closest to sqrt(N). Then the rectangle is x by N/x, both integers.
There are several issues to consider here. If you want your grid to be as square as possible, for many Ns it will have empty cells in it. A simple example is N=10. You can create a 3x4 grid for it, but it will have two empty cells. A 2x5 grid, on the other hand, will have no empty cells. Some Ns (prime numbers) will always have empty cells in the grid.
But if you just want the square and don't care about empty fields then generally yes, you should take the square root. Say your number is N. Then, take R = int(sqrt(N)). Next, do an integer division N/R, take the quotient and add 1 to it. This is C. The grid is RxC. Note that when N is a square (like 100), this is a special case so don't add 1 to the quotient.
Example:
N = 40
R = int(sqrt(N)) = 6
C = int(40 / 6) + 1 = 7
grid is 6x7
I was looking to solve this problem too for a grid in html/css that had fixed dimensions and where N items would fit. I ended up creating my own script for that in javascript.
If you're interested in the method and maths I used, you can read http://machinesaredigging.com/2013/05/21/jgridder-how-to-fit-elements-in-a-sized-grid/, it's all documented there. I used recursion and it works really well, you can use the same method for your own language. Hope this helps.
I explored Eli's answer and found something I'd like to point out. For the sake of generality, one must add 1 to C only if R x C (C = int(N/R)) is not exactly N. So, the exception includes both numbers with square root and numbers which are exactly the product of two integers.
For instance:
N = 12
R = 3
C = 4 (int(N/R))
Hope it helps.