I want to start making 2d simulations like conway's game of life, pathfinding and sand simulations and so..
I understand the concept and that I have to make a grid...
The thing is that i can't find how to make a grid..
I have tried searching and I don't seem to find a proper tutorial or something helpful...
I am using monogame framework and have some knowledge with c#.
I just want to understand how to make one so i can use it to make simulations if someone can break it down for me or give me an existing tutorial I'll be thankful.
A grid is implemented in an array of simple values(byte, uint, float...) or objects depending on complexity.
For pathfinding, it is not uncommon to use a parallel grid for indication of visited or changed nodes.
Game of life example:
// class level variables
const int WIDTH = 32;
const int HEIGHT = 32;
byte[,] Grid = new byte[WIDTH,HEIGHT]; // byte is 1/4 smaller than bool
byte[,] NextGrid = new byte[WIDTH,HEIGHT];
// 1 is alive 0 is dead
//in Initialize()
// build a period 2 Blinker
Grid[5,4] = 1;
Grid[5,5] = 1;
Grid[5,6] = 1;
//in Update()
// follow row major form and count the 8 possible live neighbors
for (int y=0;y<HEIGHT;y++)
for (int x=0;x<WIDTH;x++)
{
byte nLiveCount = 0;
if(x > 0) // left 3
{
nLiveCount += Grid[x-1,y];
if(y > 0)
nLiveCount += Grid[x-1,y-1];
if(y < HEIGHT - 1)
nLiveCount += Grid[x-1,y+1];
}
if(x < WiDTH - 1) // right 3
{
nLiveCount += Grid[x+1,y];
if(y > 0)
nLiveCount += Grid[x+1,y-1];
if(y < HEIGHT - 1)
nLiveCount += Grid[x+1,y+1];
}
if(y < HEIGHT - 1) // above
nLiveCount += Grid[x,y+1];
if(y > 0) // below
nLiveCount += Grid[x,y-1];
if(Grid[x,y]== 1) // test live
{
if((nLiveCount == 2 || nLiveCount ==3))
NextGrid[x,y] = 1;
}
else
if(nLiveCount == 3) // birth
NextGrid[x,y] = 1;
}
Grid = NextGrid;
NextGrid = new byte[WIDTH,HEIGHT]; // Ready nextGrid for next step
// in Draw()
// this assumes 2 loaded 8x8 textures called black and white
for (int y=0;y<HEIGHT;y++)
for (int x=0;x<WIDTH;x++)
spriteBatch.Draw((Grid[x,y]==1)?black:white, new Vector2(8 * x, 8 * y), Color.White);
// could be simplified to a single white texture 8x8 with:
//spriteBatch.Draw(white, new Vector2(8 * x, 8 * y), (Grid[x,y]==1) ? Color.Black : Color.White);
For this type of "game" I would rather use .NET MAUI and its Grid. The grid in Monogame can be draw either as a whole image of grid or as an array of lines, for which a 1x1px (but better is the middle pixel of 3x3px) source white image is sufficient (the color can be changed during rendering). This can then be stretched to any width or height to render the entire grid to the screen. You then need to have a 2D array (bool[,]) with a state map in the background for faster processing and redraw the result on the screen.
I have a YouTube tutorial and GitHub source code for a tower defense game in Monogame, where I also use grid layout, but it's only in Czech language.
Related
Problem
How can i find the direction of one rectangle w.r.t to the other. The directions i am interested is up, down, left, and right. My rectangle is represented by a Cell class. I am trying to write a function in that cell class. Function accepts a parameter of Cell type the returns the direction either 1(up) 2(down) 3(left), or 4(right) of the passed cell w.r.t to the calling cell.
What i tried
I found the mid point of both the rectangles, and then compared the x, and y coordinates. But this technique is not working in all the cases. whenever i find a missing case, i have to include more and more if statements which i think is not a good programming practice. its becoming more and more error prone and difficult to understand.
While searching for the solution: maybe math.atan2() can work in my case. Maybe i can find the angle between mid points of these 2 rectangles and use the value of angle to determine the direction. But i am not sure if my thinking is correct.
Please guide me. Should i keep using my function and rectify it, or is there a better solution such as math.atan2()? A helping image for better understanding and a required solution is demonstrated below after the code.
Code
public int dirOfThisCell(Cell cell)
{
int dir = 0;
//find mid points of both cells
PointF midPointThis = this.computeAndGetMidPoint();
PointF midPointCell = cell.computeAndGetMidPoint();
//MessageBox.Show(mess);
//if x of both points is same or with little variance because of variance in sizes of cells
===>> //Comparison Starts!!
if (midPointThis.X > midPointCell.X)
{
//this cell is to the right.
if ((midPointCell.Y) == (midPointThis.Y))
{
dir = 3;
}
else if (Math.Abs(midPointCell.Y) - Math.Abs(midPointThis.Y) < 5) { dir = 3; }
else if (Math.Abs(midPointCell.Y) - Math.Abs(midPointThis.Y) > 5) {
if (midPointThis.Y > midPointCell.Y) { dir = 1; }
else if (midPointThis.Y < midPointCell.Y) dir = 2;
}
// a considerable difference
else { dir = 3; }
//some small variations in y
//else if(Math.Abs()
}
else if (midPointThis.X < midPointCell.X)
{
// this cell is to the left
if ((midPointCell.Y) == (midPointThis.Y))
{
dir = 4;
}
else if (Math.Abs(midPointCell.Y) - Math.Abs(midPointThis.Y) <= 10)
{
dir = 4;
}
}
//if this cell is below
else if (midPointThis.Y > midPointCell.Y)
{
//this cell is down than the cell
if ((midPointCell.X) == (midPointThis.X))
{
dir = 1;
}
//else if (Math.Abs(midPointCell.X) - Math.Abs(midPointThis.X) < 2) { dir = 1; }
}
else if (midPointThis.Y < midPointCell.Y)
{
if ((midPointCell.X) == (midPointThis.X))
{
dir = 2;
}
}
return dir;
}
Image
Sample Image
Sample rectangles are shown in the picture number wise. The rectangle can be of single cell or made by combining multiple numbered cells.
Sample Solution required
Direction of cell 18 w.r.t to 8 should be up(1)
Direction of cell 18 w.r.t to 10 should be up(1)
Direction of cell 14 w.r.t to 13 should be right(4)
Direction of cell 9 w.r.t to 31 should be down(1)
Direction of cell 15 w.r.t to 9 should be left(3)
I am working in c#.
Any help would be much appreciated.
Thank You
Calculating the angle of the center of a rectangle compared to the center of another does not seem to be a very good idea, because the center of those rectangles are only telling you where their center is and the solution is completely reluctant to the width, height and direction of the sides. I know that the third one is not a concern in your specific case as you can safely assume that the sides are horizontal XOR vertical, but in general terms, that could be an issue as well. To calculate the relative position of Shape1 (which is a rectangle in our particular case) compared to Shape2, you need to calculate the minimum and maximum x and y for both.
Shape1 is to the left of Shape2 <=> Shape1.maxX <= Shape2.minX
Shape1 is to the right of Shape2 <=> Shape2.minX >= Shape2.maxX
Shape1 is above Shape2 <=> Shape1.maxY <= Shape2.minY
Shape2 is below Shape2 <=> Shape2.minY >= Shape1.maxY
uI am making a program to turn an image into coloured 0's, the problem is that the 0's are not colouring properly. To get anything near resembling the image I have to start my for loop at 2 and increase by 3 each time. The following is my current code:
public partial class MainWindow : Window
{
public MainWindow()
{
TextSelection textRange;
TextPointer start;
TextPointer startPos;
TextPointer endPos;
System.Drawing.Color x;
int pixelX = 3;
int pixelY = 8;
InitializeComponent();
Bitmap b = new Bitmap(#"E:\Documents\Visual Studio 2015\Projects\RichTextBox Image to ASCII\RichTextBox Image to ASCII\Akarin.jpg");
for (int i = 2; i < 8000; i += 3)
{
textRange = richTextBox1.Selection;
start = richTextBox1.Document.ContentStart;
startPos = start.GetPositionAtOffset(i);
endPos = start.GetPositionAtOffset(i + 1);
textRange.Select(startPos, endPos);
x = b.GetPixel(pixelX, pixelY);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(System.Windows.Media.Color.FromArgb(x.A, x.R, x.G, x.B)));
pixelX += 6;
if (pixelX > 1267)
{
pixelX = 3;
pixelY += 16;
}
i += 3;
textRange = richTextBox1.Selection;
start = richTextBox1.Document.ContentStart;
startPos = start.GetPositionAtOffset(i);
endPos = start.GetPositionAtOffset(i + 1);
textRange.Select(startPos, endPos);
x = b.GetPixel(pixelX, pixelY);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(System.Windows.Media.Color.FromArgb(x.A, x.R, x.G, x.B)));
pixelX += 7;
if (pixelX > 1267)
{
pixelX = 3;
pixelY += 16;
}
}
}
}
The reason that I am putting the code in the for loop twice is because when you take the amount of 0's that fit horizontally and find out how many pixels each 0 takes up, it comes to about 6.5 because of the space between each 0.
EDIT: Something else that is also strange, if you look in the top left corner where it starts colouring the 0's, 4 in a row are properly coloured, but then the rest are coloured every other.
A few serious problems I'm seeing here. Normally when rasterizing you either loop through the source pixels or through the target pixels. You however... you loop by a fixed value of roughly 2666 ((8000 - 2) / 3). It's also a very bad idea to do things twice in a loop and even change the loop variable (i). Furthermore since you're having only one loop you have to care about both axes in one run. This is very error prone.
How about this approach?:
Your source image is 1280 × 720 square pixels
Since your zeros are not square you have to know their aspect ratio. If you know that you can calculate how many rows and columns you need. You probably don't want to match them 1:1 as this would give you a huge and stretched image.
Once you know how many rows and columns you need, do two loops, one inside the other and call the loop variables targetX and targetY
If your target image is supposed to be let's say 400 zeroes long in the x-axis, make the first loop go from 1 to 400
Inside the loop pick one pixel (color) from the source at 1280/400 * targetX. Your first target pixel would be at x position 1280/400 * 1 = 3,2 which is roughly 3 (round the number after calculating it). The second would be 1280/400 * 2 = 6 and so on. I think this is the biggest pain in your algorithm since you're trying to get around the 6,5px width. Just round it after calculating! If the first is 6,5, make it 7, the second is 13... you get the idea.
Same logic goes for Y axis, but you handle this with targetY.
I want to automatically divide an image of ancient handwritten text by lines (and by words in future).
The first obvious part is preprocessing the image...
I'm just using a simple digitization (based on brightness of pixel). After that I store data into two-dimensional array.
The next obvious part is analyzing the binary array.
My first algorithm was pretty simple - if there are more black pixels in a row of the array than the root-mean-square of Maximum and Minimum value, then this row is part of line.
After forming the list of lines I cut off lines with height that is less than average.
Finally it turned out into some kind of linear regression, trying to minimize the difference between the blank rows and text rows. (I assumed that fact)
My second attempt - I tried to use GA with several fitness functions.
The chromosome contained 3 values - xo, x1, x2. xo [-1;0] x1 [0;0.5] x2 [0;0.5]
Function, that determines identity the row to line is (xo + α1 x1 + α2 x2) > 0, where α1 is scaled sum of black pixels in row, α2 is median value of ranges between the extreme black pixels in row. (a1,a2 [0,1])
Another functions, that I tried is (x1 < α1 OR x2 > α2) and (1/xo + [a1 x1] / [a2 x2] ) > 0
The last function is the most efficient.
The fitness function is
(1 / (HeigthRange + SpacesRange)
Where range is difference between maximum and minimum. It represents the homogeneity of text. The global optimum of this function - the most smooth way to divide the image into lines.
I am using C# with my self-coded GA (classical, with 2-point crossover, gray-code chromosomes, maximum population is 40, mutation rate is 0.05)
Now I ran out of ideas how to divide this image into lines with ~100% accuracy.
What is the efficient algorithm to do this?
UPDATE:
Original BMP (1.3 MB)
UPDATE2:
Improved results on this text to 100%
How I did it:
fixed minor bug in range count
changed fitness function to 1/(distancesRange+1)*(heightsRange+1))
minimized classifying function to (1/xo + x2/range) > 0 (points in row now don't affect classification)
(i.e. optimized input data and made fitness function optimizations more explicit)
Problem:
GA surprisingly failed to recognize this line. I looked at debug data of 'find rages' function and found, that there is too much noise in 'unrecognized' place.
The function code is below:
public double[] Ranges()
{
var ranges = new double[_original.Height];
for (int y = 0; y < _original.Height; y++ )
{
ranges[y] = 0;
var dx = new List<int>();
int last = 0;
int x = 0;
while (last == 0 && x<_original.Width)
{
if (_bit[x, y])
last = x;
x++;
}
if (last == 0)
{
ranges[y] = 0;
continue;
}
for (x = last; x<_original.Width; x++)
{
if (!_bit[x, y]) continue;
if (last != x - 1)
{
dx.Add((x-last)+1);
}
last = x;
}
if (dx.Count > 2)
{
dx.Sort();
ranges[y] = dx[dx.Count / 2];
//ranges[y] = dx.Average();
}
else
ranges[y] = 0;
}
var maximum = ranges.Max();
for (int i = 0; i < ranges.Length; i++)
{
if (Math.Abs(ranges[i] - 0) < 0.9)
ranges[i] = maximum;
}
return ranges;
}
I'm using some hacks in this code. The main reason - I want to minimize the range between nearest black pixels, but if there are no pixels, the value becomes '0', and it becomes impossible to solve this problem with finding optimas. The second reason - this code is changing too frequently.
I'll try to fully change this code, but I have no idea how to do it.
Q:
If there is more efficient fitness function?
How to find more versatile determination function?
Although I'm not sure how to translate the following algorithm into GA (and I'm not sure why you need to use GA for this problem), and I could be off base in proposing it, here goes.
The simple technique I would propose is to count the number of black pixels per row. (Actually it's the dark pixel density per row.) This requires very few operations, and with a few additional calculations it's not difficult to find peaks in the pixel-sum histogram.
A raw histogram will look something like this, where the profile along the left side shows the number of dark pixels in a row. For visibility, the actual count is normalized to stretch out to x = 200.
After some additional, simple processing is added (described below), we can generate a histogram like this that can be clipped at some threshold value. What remains are peaks indicating the center of lines of text.
From there it's a simple matter to find the lines: just clip (threshold) the histogram at some value such as 1/2 or 2/3 the maximum, and optionally check that the width of the peak at your clipping threshold is some minimum value w.
One implementation of the full (yet still simple!) algorithm to find the nicer histogram is as follows:
Binarize the image using a "moving average" threshold or similar local thresholding technique in case a standard Otsu threshold operating on pixels near edges isn't satisfactory. Or, if you have a nice black-on-white image, just use 128 as your binarization threshold.
Create an array to store your histogram. This array's length will be the height of the image.
For each pixel (x,y) in the binarized image, find the number of dark pixels above and below (x,y) at some radius R. That is, count the number of dark pixels from (x, y - R) to x (y + R), inclusive.
If the number of dark pixels within a vertical radius R is equal or greater to R--that is, at least half the pixels are dark--then pixel (x,y) has sufficient vertical dark neighbors. Increment your bin count for row y.
As you march along each row, track the leftmost and rightmost x-values for pixels with sufficient neighbors. As long as the width (right - left + 1) exceeds some minimum value, divide the total count of dark pixels by this width. This normalizes the count to ensure the short lines like the very last line of text are included.
(Optional) Smooth the resulting histogram. I just used the mean over 3 rows.
The "vertical count" (step 3) eliminates horizontal strokes that happen to be located above or below the center line of text. A more sophisticated algorithm would just check directly above and below (x,y), but also to the upper left, upper right, lower left, and lower right.
With my rather crude implementation in C# I was able to process the image in less than 75 milliseconds. In C++, and with some basic optimization, I've little doubt the time could be cut down considerably.
This histogram method assumes the text is horizontal. Since the algorithm is reasonably fast, you may have enough time to calculate pixel count histograms at increments of every 5 degrees from the horizontal. The scan orientation with the greatest peak/valley differences would indicate the rotation.
I'm not familiar with GA terminology, but if what I've suggested is of some value I'm sure you can translate it into GA terms. In any case, I was interested in this problem anyway, so I might as well share.
EDIT: maybe for use GA, it's better to think in terms of "distance since previous dark pixel in X" (or along angle theta) and "distance since previous dark pixel in Y" (or along angle [theta - pi/2]). You might also check distance from white pixel to dark pixel in all radial directions (to find loops).
byte[,] arr = get2DArrayFromBitamp(); //source array from originalBitmap
int w = arr.GetLength(0); //width of 2D array
int h = arr.GetLength(1); //height of 2D array
//we can use a second 2D array of dark pixels that belong to vertical strokes
byte[,] bytes = new byte[w, h]; //dark pixels in vertical strokes
//initial morph
int r = 4; //radius to check for dark pixels
int count = 0; //number of dark pixels within radius
//fill the bytes[,] array only with pixels belonging to vertical strokes
for (int x = 0; x < w; x++)
{
//for the first r rows, just set pixels to white
for (int y = 0; y < r; y++)
{
bytes[x, y] = 255;
}
//assume pixels of value < 128 are dark pixels in text
for (int y = r; y < h - r - 1; y++)
{
count = 0;
//count the dark pixels above and below (x,y)
//total range of check is 2r, from -r to +r
for (int j = -r; j <= r; j++)
{
if (arr[x, y + j] < 128) count++;
}
//if half the pixels are dark, [x,y] is part of vertical stroke
bytes[x, y] = count >= r ? (byte)0 : (byte)255;
}
//for the last r rows, just set pixels to white
for (int y = h - r - 1; y < h; y++)
{
bytes[x, y] = 255;
}
}
//count the number of valid dark pixels in each row
float max = 0;
float[] bins = new float[h]; //normalized "dark pixel strength" for all h rows
int left, right, width; //leftmost and rightmost dark pixels in row
bool dark = false; //tracking variable
for (int y = 0; y < h; y++)
{
//initialize values at beginning of loop iteration
left = 0;
right = 0;
width = 100;
for (int x = 0; x < w; x++)
{
//use value of 128 as threshold between light and dark
dark = bytes[x, y] < 128;
//increment bin if pixel is dark
bins[y] += dark ? 1 : 0;
//update leftmost and rightmost dark pixels
if (dark)
{
if (left == 0) left = x;
if (x > right) right = x;
}
}
width = right - left + 1;
//for bins with few pixels, treat them as empty
if (bins[y] < 10) bins[y] = 0;
//normalize value according to width
//divide bin count by width (leftmost to rightmost)
bins[y] /= width;
//calculate the maximum bin value so that bins can be scaled when drawn
if (bins[y] > max) max = bins[y];
}
//calculated the smoothed value of each bin i by averaging bin i-1, i, and i+1
float[] smooth = new float[bins.Length];
smooth[0] = bins[0];
smooth[smooth.Length - 1] = bins[bins.Length - 1];
for (int i = 1; i < bins.Length - 1; i++)
{
smooth[i] = (bins[i - 1] + bins[i] + bins[i + 1])/3;
}
//create a new bitmap based on the original bitmap, then draw bins on top
Bitmap bmp = new Bitmap(originalBitmap);
using (Graphics gr = Graphics.FromImage(bmp))
{
for (int y = 0; y < bins.Length; y++)
{
//scale each bin so that it is drawn 200 pixels wide from the left edge
float value = 200 * (float)smooth[y] / max;
gr.DrawLine(Pens.Red, new PointF(0, y), new PointF(value, y));
}
}
pictureBox1.Image = bmp;
After fiddling around this for a while I found that I simply need to count the number of crossings for each line, that is, a switch from white to black would count as one, and a switch from black to white would increment by one again. By highlighting each line with a count > 66 I got close to 100% accuracy, except for the bottom most line.
Of course, would not be robust to slightly rotated scanned documents. And there is this disadvantage of needing to determine the correct threshold.
IMHO with the image shown that would be so hard to do 100% perfectly.
My answer is to give you alternate idea's.
Idea 1:
Make your own version of ReCaptcha (to put on your very own pron site) - and make it a fun game.. "Like cut out a word (edges should all be white space - with some tolerance for overlapping chars on above and below lines)."
Idea 2:
This was a game we played as kids, the wire of a coat hanger was all bent in waves and connected to a buzzer and you had to navigate a wand with a ring in the end with the wire through it, across one side to the other without making the buzzer go off. Perhaps you could adapt this idea and make a mobile game where people trace out the lines without touching black text (with tolerance for overlapping chars)... when they can do a line they get points and get to new levels where you give them harder images..
Idea 3:
Research how google/recaptcha got around it
Idea 4:
Get the SDK for photoshop and master the functionality of it Extract Edges tool
Idea 5:
Stretch the image heaps on the Y Axis which should help, apply the algorithm, then reduce the location measurements and apply them on the normal sized image.
I'm working on an assignment for uni where I have to create a Breakout game in Visual Studio 2010 using C# Win Forms. At the moment, I am concentrating on there being only one brick to be destroyed so I have the mechanics down before expanding on it.
To clarify about my current program: I am using a picture box as a Graphics object and a timer to create the animation effect. The ball can skip, at each frame, between 1 and 10 pixels — this is part of creating a random starting vector for the ball.
This works fine until it comes to checking if the ball has 'hit' the brick I have drawn. What I have is an if statement that checks if the ball is at any of the coordinates on the picture box that corresponds to the outline of the brick. I know that the logic is fine because it works some of the time. However, because of the variation in the 'jumping' of the ball's position, I need to add a buffer area of +/- 5 pixels to my if statement.
This is where the problem arises, because my if statement (two, really) is really complicated as it is:
// Checks if ball hits left side or top of brick
if (((x >= brickX) && (x <= (brickX + 50)) && (y == brickY)) ||
((y >= brickY) && (y <= (brickY + 20)) && (x == brickX)))
{
brickHit = true;
}
// Check if ball hits right side or bottom of brick
else if ((((x >= brickX) && (x <= brickX + 50)) && (y == (brickY + 20))) ||
(((y >= brickY) && (y <= brickY + 20)) && (x == brickX + 50)))
{
brickHit = true;
}
For clarification: x and y are the coordinates of the ball and brickX and brickY are the coordinates of the top-left corner of the rectangle brick (which is 50 pixels wide, 10 pixels high).
Is there any way to simplify the above if statements? If I can make them simpler, I know it'll be much easier to add in the 'buffer' (which only needs to be 5 pixels either side of the brick's outline' to allow for the ball's change in position).
If further clarification is needed, please ask — I'm writing this question at 5:12am so I know I might be a little unclear.
One way you could possible simplify this (and I may be misunderstanding your spec), but you can make a Rectangle out of the bounds of the brick and check the Contains for your x,y point.
Rectangle rec = new Rectangle(brickX, brickY, 50, 20);
rec.Offset(-5, -5);
rec.Inflate(10, 10);
if (rec.Contains(new Point(x,y))
{
brickHit = true;
}
brickHit = new Rectangle(brickX,brickY,50,20).Contains(x,y);
Adding a buffer:
int buffer = 5;
brickHit = new Rectangle(brickX,brickY,50,20).Inflate(buffer,buffer).Contains(x,y);
The Rectagle class can come in handy sometimes.
This worked for me:
var rect1 = new System.Drawing.Rectangle(pictureBox1.Location,
pictureBox1.Size);
var rect2 = new System.Drawing.Rectangle(pictureBox2.Location,
pictureBox2.Size);
if (rect1.IntersectsWith(rect2))
{
//code when collided
}
I want to move through the pixels of an image, not by going line by line, column by column in the "normal" way. But begin at the center pixel and going outward in a spiral motion. But I'm not sure how to do this.
Any suggestions on how this can be done?
You can do this by using parametric functions, function for radius is r(t) = R, and x(t) = Rcos(t) and y(t)=Rsin(t).
Do you mean something like this?
It would be helpful to think about this in reverse.
For example, starting at the top left corner and moving in a clockwise direction you would move along the top row, then down the right hand side, along the bottom, and up the left edge to the pixel under the starting point.
Then move along the second row, and continue in a spiral.
Depending on the dimensions of the image you will end up with either a single column of pixels or a single row of pixels and will be moving either up/down or left/right.
From this finishing point you can then follow your steps backwards and process all the pixels as you need to.
To work out your starting position mathematically you would need to know the width/height of the image as well as which pixel you would like to end on and the direction you want to be travelling in when you get to the last pixel.
Something like this should do it:
int x = width / 2;
int y = height / 2;
int left = width * height;
int dir = 0;
int cnt = 1;
int len = 2;
int[] move = { 1, 0, -1, 0, 1 };
while (left > 0) {
if (x >= 0 && x < width && y >= 0 && y < height) {
// here you do something with the pixel at x,y
left--;
}
x += move[dir % 4];
y += move[(dir % 4) + 1];
if (--cnt == 0) {
cnt = len++ / 2;
dir++;
}
}
If the image is not square, the spiral will continue outside the coordinates of the image until the entire image has been covered. The condition in the if statement makes sure that only coordinates that are part of the image are processed.