C++ how use formula

I have formula x= x0 + sin(a)*R and how i can draw circle with it.
Last edited on
iteration. Presumably a is in radians so you can take say a double, iterate from 0 to 2 pi via a 0.1 or 0.05 type increment to get a series of points to plot. You probably also want to compute the y coordinate, which is (I think) the same thing with cos(a).
Can you write down code.
1. How does that equation define a circle? A circle is a 2D-concept.

2. C++ in itself does not draw anything. It can send characters to output. It can write files. It can call OS system functions, which in turn change color of pixels on screen.
Of course i write code to print characters wich have to made circle but it was wrong. Than i tried tu use this fotmula for X and for Y but i cant finish


That is not a formula for a circle, that is only giving the x or y coordinate of the circle, depending on how you're defining your coordinate system -- usually, the x coordinate is obtained with cos(angle), and the y coordinate is obtained with sin(angle).

Here's a program that draws a circle onto a grid using the parametric definition of a circle,
circle(t) = { R*cos(t), R*sin(t) }
It increments the angle a by a little bit each iteration.

Given a 2d array to act as grid.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
    char grid[GRID_SIZE_Y][GRID_SIZE_X];

    // fill in default values ...

    const double Pi = 3.1415926535;
    
    int num_iterations = static_cast<int>(2.0 * Pi * R + 1.5); // circumference
    for (int i = 0; i < num_iterations; i++)
    {
        double a = 2 * Pi * static_cast<double>(i) / num_iterations;
        int x = static_cast<int>( x0 + std::cos(a)*R + 0.5);
        int y = static_cast<int>( y0 + std::sin(a)*R + 0.5);
        
        grid[y][x] = '0';
    }


The grid will output something along the lines of this:
1
2
3
4
5
6
7
8
9
10
11
12
13
                                        
                0 0 0 0 0               
            0 0           0 0           
            0               0           
          0                   0         
          0                   0         
          0                   0         
          0                   0         
          0                   0         
            0               0           
            0 0           0 0           
                0 0 0 0 0               
                                       
Last edited on
Wow.mejic
And is another way. without massives only for loop
Without what? Ganado wrote a very simple loop. The code might look verbose, but that helps to see the simple thing it does.
(Currently it assumes that the circle is inside the grid. What does happen if the assumption is wrong?)


Ganado's approach computes (some) points of the circle and marks nearest grid points.
If the iterations is too low, then some grid points are left unmarked.
If the iterations is unnecessarily high, then same points will be marked multiple times.


The grid is essentially a GRID_SIZE_X*GRID_SIZE_Y pixel bitmap image, where each grid point is a pixel and each pixel is shown in the example as a character (whitespace or 0).


One can use an opposite approach. Rather than compute points on the circle, check for each grid point whether that point is on the circle.
1
2
3
4
5
6
7
for ( int row=0; row < GRID_SIZE_Y; ++row ) {
  for ( int col=0; col < GRID_SIZE_X; ++col ) {
    if ( row,col is on circle ) {
      grid[row][col] = '0';
    }
  }
}

How to test whether row,col is on circle?

The center of the circle is at 2D coordinates (x0,y0). This is point C.
The grid point is at 2D coordinates (col,row). This is point G.
The coordinates can be either integers (grid indices) or floating point values into which the indices are mapped.

IF the distance between C and G is about R, THEN G is on the circle.


If grid is large and R is small, then one should compute:
colS = max( x0-R-border, 0 )
colE = min( x0+R+border, GRID_SIZE_X )
rowS = max( y0-R-border, 0 )
rowE = min( y0+R+border, GRID_SIZE_Y )

and loop only
1
2
3
for ( int row=rowS; row < rowE; ++row ) {
  for ( int col=colS; col < colE; ++col ) {
...

The border is a little bit extra to ensure that we evaluate a sufficient area.


[EDIT]
Simple, the other way: make your program to write a file in image file format and let somebody else to do the rendering. For example SVG: https://www.w3schools.com/graphics/svg_intro.asp
Last edited on
Of course. But grid[x][y] if i am right is is named matrix. And how use grid[n] only one massive i dont know how is named is and if you can understand me......
Circles, circles, everywhere ....

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <vector>
#include <cmath>
#include <random>
#include <chrono>
using namespace std;

struct Point{ double x, y; };

void getPoints( vector<Point> &pts );
void drawgraph( const vector<Point> &pts, int width, int height, bool autoscale, double xmin = 0.0, double xmax = 1.0, double ymin = 0.0, double ymax = 1.0 );

const int WIDTH = 80, HEIGHT = 40;
const double XMIN = 0.0, XMAX = 100.0;
const double YMIN = 0.0, YMAX = 50.0;

//======================================================================


int main() 
{
   vector<Point> pts;
   getPoints( pts );
   drawgraph( pts, WIDTH, HEIGHT, false, XMIN, XMAX, YMIN, YMAX );
}


//======================================================================


void getPoints( vector<Point> &pts )
{
   const int NCIRCLES = 6;
   const int NPTS = 100;
   const double RADMIN = 3.0, RADMAX = 10.0;
   const double TwoPi = 6.283185;

   unsigned int seed( chrono::system_clock::now().time_since_epoch().count() );
   mt19937 gen( seed );
   uniform_real_distribution<double> dist( 0.0, 1.0 );

   pts.clear();

   for ( int c = 1; c <= NCIRCLES; c++ )
   {
      double x0 = XMIN + ( XMAX - XMIN ) * dist( gen );
      double y0 = XMIN + ( YMAX - YMIN ) * dist( gen );
      double R  = RADMIN + ( RADMAX - RADMIN ) * dist( gen );
      for ( int n = 0; n < NPTS; n++ )
      {
         double angle = TwoPi * n / NPTS;
         double x = x0 + R * cos( angle );
         double y = y0 + R * sin( angle );
         pts.push_back( { x, y } );
      }
   }
}


//======================================================================


void drawgraph( const vector<Point> &pts, int width, int height, bool autoscale, double xmin, double xmax, double ymin, double ymax )
{
   int i, j;
   char MARK = '*';

   if ( autoscale )
   {
      xmin = pts[0].x;
      xmax = pts[0].x;
      ymin = pts[0].y;
      ymax = pts[0].y;
      for ( Point p : pts )
      {
         if ( p.x < xmin ) xmin = p.x;
         if ( p.x > xmax ) xmax = p.x;
         if ( p.y < ymin ) ymin = p.y;
         if ( p.y > ymax ) ymax = p.y;
      }
   }

   vector<char> grid( width * height, ' ' );

   // Assign points to grid
   for ( Point p : pts )
   {
      double fx = ( p.x - xmin ) / ( xmax - xmin );
      double fy = ( p.y - ymin ) / ( ymax - ymin );
      i = fx * ( width  - 1 ) + 0.5;
      j = fy * ( height - 1 ) + 0.5;
      if ( i >= 0 && i < width && j >= 0 && j < height ) grid[j*width+i] = MARK;
   }

   // Plot 
   for ( int j = height - 1; j >= 0; j-- )
   {
      for ( int i = 0; i < width; i++ ) cout << grid[j*width+i];
      cout << endl;
   }
}


        ***  ****                                                               
       *        **                                                              
      *          *                                                              
     **           *                                                             
     *            *                                                             
     *             *                                                            
    **             *                                                            
    **             *                                                            
     *             *                                                            
     *            *                                                  *****      
     **           *                 ****                           **    **     
      *          *                ***  ***                         *      **    
       **       **               **      *                        *        *    
        ********                 *        *                       *        *    
                                 *        *                       *        *    
                                 *        *                       *        *    
                                 *        *                       **      **    
                                 **      *                         **    **     
                                  **    **                          ******      
                                    ****                                        
                                                                                
                                                                                
                                                                                
                                        *****                                   
    *****                              *    *                                   
   **    *                             *     *                                  
   *      *                            *     *                                  
   *      *                            *    **                                  
   *      *                            **  **                                   
   *      *              *****           ***                                    
   **    **             **   **                                                 
    ******              *     *                                                 
                        *     *                                                 
                        *     *                                                 
                         *   **                                                 
                          ****                                                  
                                                                                
                                                                                
                                                                                
                                                                                                                                                     
Last edited on
Topic archived. No new replies allowed.