Drawing circles on a diagonal line in C++ - c++

I've been working on this for about an hour now and I can't figure out what I'm doing wrong. This is the problem statement for the problem:
Draw a series of circles along one diagonal of a window. The circles
should be different colors and each circle should touch (but not
overlap) the one above and below it. Allow the program user to
determine how many circles are to be drawn.
These are some hints that have been given to me:
You will find the geometry involved in putting geometric elements on
the diagonals easier if you make your window square. Rather than using
getmaxheight() and getmaxwidth(), consider using getmaxheight() for
both dimensions.
Don't forget the Pythagorean theorem when working out distances in
your code such as the length of the diagonal. Keep in mind, though,
that the units on the screen are pixels, so fractions in the
computations are not too useful. This is definitely a place for
integer arithmetic.
Use the number of elements you are going to draw (squares, circles,
etc) to divide up the total length into steps for your loops to work
with.
Use for loops to draw figures when you know how many to draw, and what
size they are to be. Determine the count and size before the loop.
So far this is the code that I have created. Inputting 4 circles only draws 3 on screen, with the third one partially off screen. The circles also do not touch, which makes no sense to me because moving the center of the next circle down and over by the length of the diameter should have to the two circles touching. This is the code I have:
#include <graphics.h>
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int foreColor;
int diagLength;
int radius,diameter;
int centerX = 0, centerY = 0;
int numCircles; // number of circles.
int width, height; // screen width and height
cout << "Enter number of circles: ";
cin >> numCircles;
width = getmaxheight();
height = getmaxheight();
initwindow(width, height, "Circles");
diagLength = sqrt((width * width) + (height * height));
diameter = diagLength / numCircles;
radius = diameter / 2;
centerX = radius;
centerY = radius;
for (int i = 1; i <= numCircles; i++)
{
foreColor = i % 16; // 0 <= foreColor <= 15
setcolor(foreColor);
setfillstyle(i % 12, foreColor); // Set fill style
fillellipse(centerX, centerY, radius, radius);
centerX = centerX + diameter;
centerY = centerY + diameter;
}
getch(); // pause for user
closegraph();
}

Here's a diagram of what I think you want:
The basic problem comes down to determining
What the diameter D of each circle is
Where the center of each circle is.
The diameter is easy. First calculate the length L of the diagonal using Pythagoras' theorem, then divide by the desired number of circles N. Of course, if you need the radius just divide again by 2.
L = Sqrt(Width * Width + Height * Height);
D = L / N;
The trick to working out the position of the circle centers is to realise that the X are evenly spaced along the X axis, and same with the Y coordinates - so you can work out the distances I've labelled Dx and Dy really easily using the same division:
Dx = Width / N;
Dy = Height / N;
From there the center of each circle is easily calculated:
for (i = 0; i < N; i++)
{
centerX = (Dx / 2) + i * Dx;
centerY = (Dy / 2) + i * Dy;
/* Draw the circle at (centerX, centerY) with diameter D */
}
That's all there is to it!
By the way, if you were wondering why your code was drawing circles further apart than they should be, the reason is because you were adding D to centerX and centerY rather than Dx and Dy.

Related

perlin noise giving diffrent values for same point after player has moved [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 months ago.
Improve this question
I am using perlin noise to generate a map for my game. This is then being drawn using marching squares. The values That are being input for the perlin noise function are relative to a 0,0 coordinate and then this is converted to a position on screen that can then be drawn to.
The problem is that when the player moves the image that is drawn to the screen is slightly different at the edges of the mesh this causes a flickering effect when the player is moving.
asteroids_in_range(player.x-WIDTH/2,player.x+WIDTH/2,player.y-HEIGHT/2,player.y+HEIGHT/2,16);
int get_asteroid_case(float x, float y, float box_size)
{
/*get the case for the box with the bottom left corner
at location x,y and size of box_size*/
int count = 0;
if(perlin.GetValue(x, y, 0.1) > THRESHHOLD)
{
count += 8;
}
if(perlin.GetValue(x+box_size, y, 0.1) > THRESHHOLD)
{
count += 4;
}
if(perlin.GetValue(x+box_size, y+box_size, 0.1) > THRESHHOLD)
{
count += 2;
}
if(perlin.GetValue(x, y+box_size, 0.1) > THRESHHOLD)
{
count += 1;
}
return count;
}
void asteroids_in_range(float xmin, float xmax, float ymin, float ymax, float grid_size)
{
int num;
for(float x = xmin; x <= xmax; x+=grid_size)
{
for(float y = ymin; y <= ymax; y+=grid_size)
{
num = get_asteroid_case(x, y, grid_size);
if(num != 0 && num != 15)
render_asteroids(num,x,y, 1);
}
}
}
Images with the player one pixel apart as can be seen, there are subtle differences on the fringes of the generated meshes.
Your problem is you are getting different noise values because you are getting the noise at different points. Don't do that. Make it the same points - the ones on the grid.
Let's say grid_size is 10 (pixels) and WIDTH is 100 (pixels) and the player is at 0,0. You are getting the noise at -50,-50, and -40,-50, and -30,-50, and so on.
Now say the player moves 3 pixels right. You are getting the noise at -47,-50, and -37,-50, and -27,-50, and so on. Obviously you get different noise values, because you asked for different noise values!
Instead you should round the noise coordinates to the grid - to multiples of grid_size. Your code can easily be adapted by rounding xmin and xmax and ymin and ymax before the grid rendering - for example:
xmin = floor(xmin / grid_size) * grid_size;
xmax = ceil(xmax / grid_size) * grid_size;
// same for y
The min coordinate is rounded down, and the max coordinate is rounded up, to make sure the entire screen is still inside the rendered coordinates.

How to check if two circles drawn on an Adafruit TFT screen are touching eachother?

im making (or rather, trying to make, lol) a snake game on a Adafruit TFT 1.8 screen. Then i ofcourse need the snakehead to know when it hits the "point", and therefore i need to know when the two circles which are of even size are touching eachother. However, my function for this is not working (in other words printing "NOT TOUCHING").
Im trying to follow this formula:
(sqrt(dx2 + dy2))
The radius of both circles are 3, and i get the center for the formula from adding the screen position x and y of the circles together (am i even getting the centers correctly?).
void pointCondition() {
double centerPoint = pointPositionX + pointPositionY;
double centerSnakeHead = positionX + positionY;
int distanceBetweenCenter = (sqrt(centerPoint * 3 + centerSnakeHead * 3));
int weight = 3 / 2;
if (distanceBetweenCenter < weight) {
Serial.println("TOUCHING");
} else {
Serial.println("NOT TOUCHING");
}
}
Can you see what i am doing wrong?
You need something like this:
double dx = pointPositionX - positionX,
dy = pointPositionY - positionY,
d = sqrt(dx * dx + dy * dy);
bool touching = d <= 3;

Drawing a circle in SDL 2, but each circle uses CPU a lot

i wrote a code that draw filled circle, but it uses CPU a lot.
The thing is i draw pixel by pixel, first outter circle with radius n the second circle with radius n-1 and so on while n is not equal to 0.
I'm drawing 4 pixel in e cycle, for each circle part. Every part, as i thought, has ~ Pi/(2*R) pixels, but it is not enough and circle fill wrong, so i used Pi/(4*R) and now circle fills normaly.
Deg0 = 0;
Deg90 = M_PI / 2;
DegStep = Deg90 / (R * 4);
CurrDeg = Deg0;
OffsetX = R;
OffsetY = 0;
TmpR = R;
while(TmpR>0 )
{
while(CurrDeg < Deg90)
{
OffsetX = cos(CurrDeg) * TmpR;
OffsetY = sin(CurrDeg) * TmpR;
SDL_RenderDrawPoint(Renderer, CX+(int)OffsetX, CY+(int)OffsetY);
SDL_RenderDrawPoint(Renderer, CX-(int)OffsetY, CY+(int)OffsetX);
SDL_RenderDrawPoint(Renderer, CX-(int)OffsetX, CY-(int)OffsetY);
SDL_RenderDrawPoint(Renderer, CX+(int)OffsetY, CY-(int)OffsetX);
CurrDeg+=DegStep;
}
CurrDeg = Deg0;
TmpR-=1;
}
So, is there any way to improve my realisation?
You could use the circle drawing capabilities of SDL, or you could optimize your own code by not actually using cos and sin. Use lookup tables instead.

How to draw a filled circle?

I'm creating bitmap/bmp files according to the specifications with my C code and I would like to draw simple primitives on my bitmap. The following code shows how I draw a rectangle on my bitmap:
if(curline->type == 1) // draw a rectangle
{
int xstart = curline->x;
int ystart = curline->y;
int width = curline->width + xstart;
int height = curline->height + ystart;
int x = 0;
int y = 0;
for(y = ystart; y < height; y++)
{
for(x = xstart; x < width; x++)
{
arr[x][y].blue = curline->blue;
arr[x][y].green = curline->green;
arr[x][y].red = curline->red;
}
}
printf("rect drawn.\n");
}
...
save_bitmap();
Example output:
So basically I'm setting the red, green and blue values for all pixels within the given x and y field.
Now I'd like to fill a circle by knowing its midpoint and radius. But how do I know which pixels are inside this circle and which pixels ain't? Any help would be appreciated, thanks for reading.
A point lies within the bounds of a circle if the distance from the point to the center of the circle is less than the radius of the circle.
Consider a point (x1,y1) compared to a circle with center (x2,y2) and radius r:
int dx = x2 - x1; // horizontal offset
int dy = y2 - y1; // vertical offset
if ( (dx*dx + dy*dy) <= (r*r) )
{
// set pixel color
}
You can also try the midpoint algorithm, here on wikipedia.

How to determine Scale of Line Graph based on Pixels/Height?

I have a problem due to my terrible math abilities, that I cannot figure out how to scale a graph based on the maximum and minimum values so that the whole graph will fit onto the graph-area (400x420) without parts of it being off the screen (based on a given equation by user).
Let's say I have this code, and it automatically draws squares and then the line graph based on these values. What is the formula (what do I multiply) to scale it so that it fits into the small graphing area?
vector<int> m_x;
vector<int> m_y; // gets automatically filled by user equation or values
int HeightInPixels = 420;// Graphing area size!!
int WidthInPixels = 400;
int best_max_y = GetMaxOfVector(m_y);
int best_min_y = GetMinOfVector(m_y);
m_row = 0;
m_col = 0;
y_magnitude = (HeightInPixels/(best_max_y+best_min_y)); // probably won't work
x_magnitude = (WidthInPixels/(int)m_x.size());
m_col = m_row = best_max_y; // number of vertical/horizontal lines to draw
////x_magnitude = (WidthInPixels/(int)m_x.size())/2; Doesn't work well
////y_magnitude = (HeightInPixels/(int)m_y.size())/2; Doesn't work well
ready = true; // we have values, graph it
Invalidate(); // uses WM_PAINT
////////////////////////////////////////////
/// Construction of Graph layout on WM_PAINT, before painting line graph
///////////////////////////////////////////
CPen pSilver(PS_SOLID, 1, RGB(150, 150, 150) ); // silver
CPen pDarkSilver(PS_SOLID, 2, RGB(120, 120, 120) ); // dark silver
dc.SelectObject( pSilver ); // silver color
CPoint pt( 620, 620 ); // origin
int left_side = 310;
int top_side = 30;
int bottom_side = 450;
int right_side = 710; // create a rectangle border
dc.Rectangle(left_side,top_side,right_side,bottom_side);
int origin = 310;
int xshift = 30;
int yshift = 30;
// draw scaled rows and columns
for(int r = 1; r <= colrow; r++){ // draw rows
pt.x = left_side;
pt.y = (ymagnitude)*r+top_side;
dc.MoveTo( pt );
pt.x = right_side;
dc.LineTo( pt );
for(int c = 1; c <= colrow; c++){
pt.x = left_side+c*(magnitude);
pt.y = top_side;
dc.MoveTo(pt);
pt.y = bottom_side;
dc.LineTo(pt);
} // draw columns
}
// grab the center of the graph on x and y dimension
int top_center = ((right_side-left_side)/2)+left_side;
int bottom_center = ((bottom_side-top_side)/2)+top_side;
You are using ax^2 + bx + c (quadratic equation). You will get list of (X,Y) values inserted by user.
Let us say 5 points you get are
(1,1)
(2,4)
(4,1)
(5,6)
(6,7)
So, here your best_max_y will be 7 and best_min_y will be 1.
Now you have total graph area is
Dx = right_side - left_side //here, 400 (710 - 310)
Dy = bottom_side - top_side //here, 420 (450 - 30)
So, you can calculate x_magnitude and y_magnitude using following equation :
x_magnitude = WidthInPixels / Dx;
y_magnitude = HeightInPixels / Dy;
What I did was to determine how many points I had going in the x and y directions, and then divide that by the x and y dimensions, then divide that by 3, as I wanted each minimum point to be three pixels, so it could be seen.
The trick then is that you have to aggregate the data so that you are showing several points with one point, so it may be the average of them, but that depends on what you are displaying.
Without knowing more about what you are doing it is hard to make a suggestion.
For this part, subtract, don't add:
best_max_y+best_min_y as you want the difference.
The only other thing would be to divide y_magnitude and x_magnitude by 3. That was an arbitrary number I came up with, just so the users could see the points, you may find some other number to work better.