Finding all grid coordinates within a 7x7 grid - c#

This isn't really a C# question, BUT I am doing this in C# and hopefully some individuals here can educate me on functions within the Math class, or help me find a good algorithm for this anyhow.
We'll use this example. I'm at coordinate 10, 10. I want to find all coordinates that are within a 7x7 grid, using 10, 10 as the center of it. Can anyone suggest a good algorithm, or use of the Math class to find all the coordinates I need?

This code make grid of '1' in the arr[15,15] with center at 10,10.
int x = 10, y = 10;
int lConerX = x - 4, lConerY = y - 4;//coords of top-left conner
for (int i = lConerX; i < lConerX + 7; i++)
{
for (int j = lConerY; j < lConerY + 7; j++)
{
arr[i, j] = 1;
}
}

It seems you just need double cycle by X and Y coordinates
pseudocode
X0=10
Y0=10
ASize = 7
HalfSize = ASize / 2
for Y = Y0 - HalfSize to Y0 + ASize - HalfSize do
for X = X0 - HalfSize to X0 + ASize - HalfSize do
output Y,X coordinates

Related

How to draw projectile motion path in c# .NET Framework console app?

GitHub link: https://github.com/pthdaniel/ProjectileMotion/tree/master
Hey, I was working on a project where my app should calculate the datas with the initial velocity, angle and height of the motion, and now my only problem is with the path the projectile makes. I had an idea to make a 2D string array to simulate it, but either the idea itself or my calculations are incorrect. For the array I round the double type datas and then cast them to integers.
public Canvas(int height, int width)
{
this.height = height;
this.width = width;
board = new string[height+1, width+1]; //indexing needs more space
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
board[i, 0] = "|";
board[height - 1, j] = "-";
}
}
board[height - 1, 0] = "O";
board[(int)Math.Round(Program.p.Y0), 0] = "+";
for (int j = 1; j < width; j++)
{
board[Program.p.OtherPosition(j), j] = "+";
}
}
Here is the constructor of my Canvas class which fills up my string[,] board. The Program.p is the projectile itself, which has attributes like y0, which is the initial height. The OtherPosition takes in the j to calculate, where should the method place the * character, where the x position = j. Like this:
public int OtherPosition(int position)
{
y = y0 + v0y * (position / (2 * v0x)) - (g / 2) * Math.Pow(position / (v0x * 2), 2);
return (int)(Math.Round(Program.p.Ymax, 1) * 2)+1- 2 * ((int)Math.Round(y));
}
The canvas generation is the following:
static void GenerateCanvas(Projectile p)
{
int height = (int)(Math.Round(p.Ymax,5)*2);
int width = (int)(Math.Round(p.Xmax,5)*2);
board = new Canvas(height, width);
}
The *2 multiplier is there for the bigger size of the whole biard itself.
Can somebody help me to smoothen the path? Sometimes there are * characters underneath each other, which I have no idea how. Or what's another way of doing it?

creating gabor texture in c#

I am trying to create a texture (in a 3-D byte array) that is a coloured gabor patch. I am using OpenTK to map the texture. The texture mapping is working fine, but the texture that is created by my code below is not what I need.
The code I have come up with is as follows:
for (int x = 0; x < size; x++)
{
for (int y = 0; y < size; y++)
{
double sin_term = 0.5*(double)Math.Sin(10 * 3.14159 * ((double)x / (double)size));
sin_term += 0.5;
double gauss = 0.5+Math.Exp(-((Math.Pow(x,2)+Math.Pow(y,2))/(2*Math.Pow(sigma,2))));
double gabor = sin_term * gauss;
byteTexture2[j,i,0] = (byte)(((double)Colour.R * gabor));
byteTexture2[j,i,1] = (byte)(((double)Colour.G * gabor));
byteTexture2[j,i,2] = (byte)(((double)Colour.B * gabor));
}
}
My maths isn't alll that good, so I may be off track but I was trying to multiply the sine wave by the gaussian. The sine wave term seems to work OK by itself but the gaussian may be where it is having problems.
Any help would be much appreciated.
Have found MATLAB code for this problem but no c/c++/c# code
Thanks.
I recently coded up a Gabor filter kernel for use in OpenCV (using C++). Here is my code for the kernel:
/// compute Gabor filter kernels
for (int i = 0; i < h; i++){
x = i - 0.5*(h - 1);
for (int j = 0; j < h; j++) {
y = j - 0.5*(h - 1);
gaborKernelCos.at<float>(i, j) = exp((-16 / (h*h))*(x*x + y*y))*cos((2 * M_PI*w / h)*(x*cos(q) + y*sin(q))) / (h*h);
gaborKernelSin.at<float>(i, j) = exp((-16 / (h*h))*(x*x + y*y))*sin((2 * M_PI*w / h)*(x*cos(q) + y*sin(q))) / (h*h);
}
}
Where the input parameters are the kernel size h, wave number w, and filter orientation q. Note the wave number is related to the filter pixel wavelength by l = h/w. Also, my value for sigma is simply a constant multiple of h.
This shouldn't really produce anything wildly different from your code as far as I can tell. Does your value for sigma make sense? It should probably be at most sigma = 0.5*size.

Inward spiral algorithm not working

I have this c# code to iterate through a grid in an inward spiral like this:
1 2 3
8 9 4
7 6 5
Here is the code, but there is something wrong with it, for some reason it is taking much longer than expected to compute. Does anyone know why this is happening?
static void create_spiral_img(int width, int height)
{
Bitmap img = new Bitmap(width, height);
Graphics graph = Graphics.FromImage(img);
int x = 0;
int y = 0;
int size = width * height;
int max = size;
int count = 1;
int i, j;
while (size > 0)
{
for (i = y; i <= y + size - 1; i++)
{
draw_pixel(count++, x, i, graph);
}
for (j = x + 1; j <= x + size - 1; j++)
{
draw_pixel(count++, j, y + size - 1, graph);
}
for (i = y + size - 2; i >= y; i--)
{
draw_pixel(count++, x + size - 1, i, graph);
}
for (i = x + size - 2; i >= x + 1; i--)
{
draw_pixel(count++, i, y, graph);
}
x = x + 1;
y = y + 1;
size = size - 2;
Console.Write(100 * ((float)(count) / (float)max) + "% ");
}
graph.Dispose();
img.Save("./" + width + "x" + height + "_spiril.png", System.Drawing.Imaging.ImageFormat.Png);
img.Dispose();
}
Assuming a square (width=height) it looks like you've got an O(x^4) implementation - that's going to be hideously slow.
I would recommend trying to drop it down to O(x^2). Instead of drawing it spirally, rewrite your algorithm to draw it rectangularly - that is, go by rows & columns, calculating what each pixel should be.
Assuming that
draw_pixel(c,x,y,g)
draws a point in color c at (x,y) coordinates in the graph g, you're going way too far. You're doing
for (i = y; i <= y + size - 1; i++)
to print a line that should have length width, but you're printing a line of length size.
I'm thinking I didn't understand your algorithm. If this doesn't make sense, can you explain the semantics of draw_pixel please ?

Algorithm to find rectangles

I have the following code:
int width = 10;
int height = 7;
bool[,] array1 = new bool[width, height];
string values =
"1100000000" +
"1100000011" +
"0001100011" +
"0001100000" +
"0001110000" +
"0000000110" +
"0000000110";
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
array1[x, y] = (values[x + y * width] == '1');
}
}
im looking for a algorithm that would extract Ranges where we have a 1.
so from this data we would get rectangles
(0,0,2,2),
(8,1,2,2),
(3,2,3,3),
(7,5,2,2)
the order of the rectangles do not matter!
But i have no idea how to do this any one got any pointers?
After reading Rusty Weber answer i came up with the following:
private static List<Rectangle> GetRectangles(bool[,] array)
{
List<Rectangle> rectangles = new List<Rectangle>();
for (int x = 0; x < array.GetLength(0); x++)
{
for (int y = 0; y < array.GetLength(1); y++)
{
if (array[x, y])
{
rectangles.Add(GetRectangle(array, new Point(x, y)));
}
}
}
return rectangles;
}
static Rectangle GetRectangle(bool[,] array, Point startLocation)
{
int maxX = int.MinValue;
int minX = int.MaxValue;
int maxY = int.MinValue;
int minY = int.MaxValue;
HashSet<Point> visitedLocations = new HashSet<Point>();
Stack<Point> pointsToGo = new Stack<Point>();
Point location;
pointsToGo.Push(startLocation);
while (pointsToGo.Count > 0)
{
location = pointsToGo.Pop();
if (!location.X.IsBetween(0, array.GetLength(0) - 1))
continue;
if (!location.Y.IsBetween(0, array.GetLength(1) - 1))
continue;
if (!array[location.X, location.Y])
continue;
if (visitedLocations.Contains(location))
continue;
visitedLocations.Add(location);
pointsToGo.Push(new Point(location.X + 1, location.Y));
pointsToGo.Push(new Point(location.X, location.Y + 1));
pointsToGo.Push(new Point(location.X - 1, location.Y));
pointsToGo.Push(new Point(location.X, location.Y - 1));
}
foreach (Point location2 in visitedLocations)
{
array[location2.X, location2.Y] = false;
if (location2.X > maxX)
maxX = location2.X;
if (location2.X < minX)
minX = location2.X;
if (location2.Y > maxY)
maxY = location2.Y;
if (location2.Y < minY)
minY = location2.Y;
}
return new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);
}
public static bool IsBetween<T>(this T item, T start, T end)
{
return Comparer<T>.Default.Compare(item, start) >= 0
&& Comparer<T>.Default.Compare(item, end) <= 0;
}
COMMENT :: It might help me to answer your question if you have better defined coordinates. (0,0,2,2) isn't exactly Cartesian and it may need some explaining. Is this the top left corner followed by the widths?
Ok. The easiest to program way, in my opinion at least, to extract all possible rectangles from the graph is to have a recursively defined method that searches in a specific direction for the symmetric rectangle pattern. This however could end up being really slow so I hope that speed isn't a constraint for you. Looking at the style of code, I would say that this is a school assignment for either recursion or dynamic programming.
something along the lines of the following pseudocode
`
for i in width
{
for j in height
{
if(point[i,j] == 1)
{
potentials = searh_in_direction(i,j,graph,width,height,RIGHT,[[i,j]] )
listOfAllRects.append(potentials)
}
}
}
list_of_rectangle searh_in_direction(i,j,graph,width,height,direction, listofpoints )
{
nextdirection = direction.nextdirection; //Right -> down -> left-> up
//DEVELOP METHOD FOR RECURSION HERE THAT RETURNS ALL SETS OF 4 POINTS THAT
for every point in the direction of travel
if the point is the origional point and we have 4 points including the point we are looking at, we have a rectangle and we need to return
if point on direction of travel is a one travel on the next direction
posiblerects.append(searh_in_direction(i,j,graph,width,height,nextdirection , listofpoints.append(currentpoint)))
//after all points in direction have bee searched
return posiblerects.
}
`
I know that this code could be very confusing but that is the gist of what you need as a recursive element.
I will also note that I can already see several bugs in this code but I have run out of the 15 minutes that I said that I was going to spend on this post so you might have to pick them out yourself.
This gives you the same results you're looking for:
static void Main(string[] args)
{
string values =
"1100000000" +
"1100000011" +
"0001100011" +
"0001100000" +
"0001110000" +
"0000000110" +
"0000000110";
int width = 10;
int height = 7;
bool[,] array = new bool[width, height];
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
array[x, y] = (values[x + y * width] == '1');
List<Rectangle> rectangles = new List<Rectangle>();
for (int x = 0; x < width; ++x)
{
for (int y = 0; y < height; ++y)
{
if (array[x, y] && !Used(rectangles, x, y))
{
int rHeight = 1;
for (int rX = x + 1; rX < width && array[rX, y] && !Used(rectangles, rX, y); ++rX)
for (int rY = y + 1; rY < height && array[rX, rY] && !Used(rectangles, rX, rY); ++rY)
if (rY - y >= rHeight)
rHeight = rY - y + 1;
int rWidth = 1;
for (int rY = y + 1; rY < height && rY - y <= rHeight && array[x, rY] && !Used(rectangles, x, rY); ++rY)
for (int rX = x + 1; rX < width && array[rX, rY] && !Used(rectangles, rX, rY); ++rX)
if (rX - x >= rWidth)
rWidth = rX - x + 1;
rectangles.Add(new Rectangle(x, y, rWidth, rHeight));
}
}
}
foreach (Rectangle rect in rectangles)
Console.WriteLine(rect);
}
private static bool Used(IEnumerable<Rectangle> rectangles, int x, int y)
{
return rectangles.Any(r => r.Contains(x, y));
}
I made an adhoc Rectangle struct since I didn't reference System.Drawing, but you can pass a System.Drawing.Point to the System.Drawing.Rectangle.Contains() and get the same results.
Also, notice that the width of your array should actually be 10 and your indexing math was wrong. You should be multiplying y by the width, not the height.
It is not clear from the question if you really want rectangles that cover the 1's exactly, or if you want bounding volumes that can contain zeroes, but will cover all the 1's with a reasonably small number of rectangles.
Assuming you want rectangles to cover the 1's, and you don't need a perfect solution:
Make a temporary copy of the array.
Iterate over the temporary looking for 1's
When you hit a 1, begin a new rectagle that starts as 1x1, offset to that location ( e.g. covers just that 1 )
Expand that rectangle rightward so long as there is a 1 in the next cell
Expand that rectangle downards so long as the row below has 1's matching the width
of the current rectangle.
ONce you can't expand down any more, emit that recgantle, and clear all the 1's covered by that rectangle from the temporary
continue scanning for 1's starting with the cell directly after the top right corner of the current rectangle.
This will produce a decent covering - but by no means ideal. If you need a perfect covering - e.g. the guaranteed minimum number of rectangles then it is harder.

Generating terrain in C# using perlin noise

I'm working on civilization game in C# and XNA. I use a two dimensional integer array, populated with a loop, to generate tiles, I've done a ton research and have been unable to find a way to generate earth like terrain. Can anyone explain how to do this or at least give me code that could do it, though I would prefer and explanation? Thank you.
I use an algorithm similar to this to make my terrain. Basicly it generates some random numbers and uses a sine wave to generate hills, when combined they give a nice hilly landscape. Note that you can add a loop and array of values if you want more than just 3 passes.
private void GenerateTerrain()
{
terrainContour = new int[Width*Height];
//Make Random Numbers
double rand1 = randomizer.NextDouble() + 1;
double rand2 = randomizer.NextDouble() + 2;
double rand3 = randomizer.NextDouble() + 3;
//Variables, Play with these for unique results!
float peakheight = 20
float flatness = 50
int offset = 30;
//Generate basic terrain sine
for (int x = 0; x < Width; x++)
{
double height = peakheight / rand1 * Math.Sin((float)x / flatness * rand1 + rand1);
height += peakheight / rand2 * Math.Sin((float)x / flatness * rand2 + rand2);
height += peakheight / rand3 * Math.Sin((float)x / flatness * rand3 + rand3);
height += offset;
terrainContour[x] = (int)height;
}
}
Then to fill the heightmap just loop through the values and check if it is above the threshold or not.
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
if (y > terrainContour[x])
tiles[x, y] = Solid Tile
else
tiles[x, y] = Blank Tile
}
}
Theres much more you can add to it, I've added more randomness and indenting some tiles by 1 up or down for better terrain. And adding more sine waves will make it more realistic.
Try using 2D Perlin Noise algorithms, and selecting certain heights to make caves and more advanced terrain, as this is now what I do, but this code here is a good start.

Categories

Resources