I just understood the concept of making a triangle in C++ that is made of asterisks.
Now that I tried to replace those asterisks by "diamonds of asterisks", I found a very
logic error and that is the "newline" and I can't find it anymore, can anyone help me
with my code?
I want my output to be like a triangle with asterisks, but the asterisks is substituted by asterisks of diamonds.
#include<iostream>
using namespace std;
int main()
{
int number, space1, space2, space3;
int i, j, x, y, z;
cout << "Enter any number: ";
cin >> number;
space1 = (2*number)-1;
space2 = number-1;
space3 = space1*space2;
z = number-1;
for(i = 1; i <= number; i++)
{
for(j = 1; j <= (2*i)-1; j++){
for (x = 1; x <= number; x++)
{
for(y = 1; y <= space3; y++)
{
cout << " ";
}
for(y = 1; y <= number-x; y++)
{
cout << " ";
}
for(y = 1; y <= (2*x)-1; y++)
{
cout << "*";
}
for(y = 1; y <= z; y++)
{
cout << " ";
}
z--;
if(x <= number)
{
cout << endl;
}
}
if(z >= 3)
{
z = 1;
}
for(x = 1; x <= number-1; x++)
{
for(y = 1; y <= space3; y++)
{
cout << " ";
}
for(y = 1; y <= x; y++)
{
cout << " ";
}
for(y = 2*(number-x)-1; y >= 1; y--)
{
cout << "*";
}
for(y = 1; y <= z; y++)
{
cout << " ";
}
z++;
if(x <= number)
{
cout << endl;
}
}
}
space3 -= space1;
}
}
Not sure what you’re really asking (asterisks that are diamonds?) – some example of the desired output could have helped! – but I like this program:
#include <iostream>
#include <string>
using namespace std;
auto main() -> int
{
for( int y = 0; y < 32; ++y )
{
cout << string( 32 - y, ' ' );
for( int x = 0; x < 32; ++x )
cout << (x & ~y? ' ' : '*') << ' ';
cout << endl;
}
}
Output:
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Related
#include <math.h>
#include <iostream>
using namespace std;
void graph(){
int x=140;
int y=20;
double convert = 3.141592/180;
cout<<"amplitude, frequency\n";
double amp,freq;
cin>>amp>>freq;
for(int i=0; i<y; i++){
for(int j=0; j<x; j++){
if(i==nearbyint(3*amp*cos(5*freq*j*convert))+10){
cout<<"*";
}
else if(i==y/2){
cout<<"-";
}
else if(j==x/2){
cout<<"|";
}
else{
cout<<" ";
}
}
cout<<endl;
}
}
int main(){
graph();
return 0;
}
when the code is run, the graph will do fine until you start inputting numbers above 4, where then the line will start having large spaces in between the *'s in the y axis.
What is the simplest way I can fill in the gaps between the *s
The equation is multiplied with 3 and 5 for formatting purposes.
I can think of some ways to do this.
The easiest way is just to check against the interval (j-0.5,j+0.5) by replacing the test
if(i==nearbyint(3*amp*cos(5*freq*j*convert))+10){
cout<<"*";
}
with
void graph( double amp, double freq ){
int x=140;
int y=20;
double convert = 3.141592/180;
for(int i=0; i<y; i++){
for(int j=0; j<x; j++){
double jx = j;
double v1 = 3*amp*cos(5*freq*(jx-0.5)*convert)+10;
double v2 = 3*amp*cos(5*freq*(jx+0.5)*convert)+10;
if( ((i>=v1)&&(i<=v2)) || ((i<=v1)&&(i>=v2))){
cout<<"*";
}
else if(i==y/2){
cout<<"-";
}
else if(j==x/2){
cout<<"|";
}
else{
cout<<" ";
}
}
cout<<endl;
}
}
Godbolt Link: https://godbolt.org/z/G47WjqafP
This results in
Program stdout
|
|
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * * *
* * * * * * * * * * | * * * * * * * * *
* * * * * * * * * * | * * * * * * * * *
* * * * * * * * * * | * * * * * * * * *
----*------*------*------*------*-------*------*------*------*------*-------*------*------*------*------*-------*------*------*------*------
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * *| * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * *
* * * * * * * * * |* * * * * * * * * *
|
But the coolest I could find for a 10 minute Blitz code project is an approach where you can use something like the Bresenham line algorithm. Bresenham will guarantee that the space between two adjacent point while drawing a line is maximum one pixel, which is exactly what you are asking.
I could apply Bresenham straight to your algorithm but why not extend this to make it more generic? I'm already wasted so here we go...
First you need to define a viewport for your graph that will map between fictitious coordinates to screen coordinates.
struct Extents {
double x[2];
double y[2];
};
Second you will need a class to hold a virtual screen with a character buffer inside and some way to clear it up.
This map will contain characters that will be printed out later.
template< int WIDTH, int HEIGHT >
struct Graph {
Extents ext;
char map[WIDTH][HEIGHT];
void clear() {
memset( map, ' ', WIDTH*HEIGHT );
}
void print() {
for ( int i=0; i<HEIGHT; ++i ) {
for ( int j=0; j<WIDTH; ++j ) {
std::cout << map[j][HEIGHT-i-1];
}
std::cout << std::endl;
}
}
};
Then you need some methods to convert from viewport to screen and vice versa
double from_screen_x( int j ) {
return ext.x[0] + (j*(ext.x[1]-ext.x[0]))/WIDTH;
}
int from_viewport_x( double x ) {
return (x-ext.x[0])/(ext.x[1]-ext.x[0])*WIDTH;
}
int from_viewport_y( double y ) {
return HEIGHT*((y-ext.y[0])/(ext.y[1]-ext.y[0]));
}
Then once we have a way to convert from (x,y) to (i,j) screen coordinates, we can easily 'plot' a single point with a given character.
void point( int x, int y, char ch ) {
if ( (x>=0) && (x<WIDTH) ) {
if ( (y>=0) && (y<HEIGHT) ) {
map[x][y] = ch;
}
}
}
Now the workhorse of the entire class - the Bresenham algorithm which you can find on Wikipedia
void line( int x0, int y0, int x1, int y1, char ch ) {
int dx = abs(x1 - x0);
int sx = x0 < x1 ? 1 : -1;
int dy = - int( abs(y1 - y0) );
int sy = y0 < y1 ? 1 : -1;
int error = dx + dy;
while( true ) {
point(x0, y0, ch);
if ( (x0 == x1) && (y0 == y1) ) break;
int e2 = 2 * error;
if ( e2 >= dy ) {
if (x0 == x1) break;
error = error + dy;
x0 = x0 + sx;
}
if (e2 <= dx) {
if (y0 == y1) break;
error = error + dx;
y0 = y0 + sy;
}
}
}
Then we need the high level functions: one to draw the axis and another to plot the chart.
The axis is easy - just find the screen coordinates of the origin (0,0) and plot it on our 'map'.
void axis() {
int i = from_viewport_y(0);
for ( int j=0; j<WIDTH; ++j ) {
point(j,i,'-');
}
int j = from_viewport_x(0);
for ( int i=0; i<HEIGHT; ++i ) {
point(j,i,'|');
}
}
For the chart algorithm I decided to go fancy and using a templated function that will allow us to externalize the actual computation.
This algorithm will sweep the x axis in screen space, map into the viewport, compute the point in virtual coordinates and bring them back to the actual (i,j) screen coordinates. Once we have obtained the first point we can from the 2nd point call the line algorithm between the old and the new point and keep iterating until the end.
template< typename Fn >
void chart( char ch, Fn&& fn ) {
int lasti = 0;
for ( int j=0; j<WIDTH; ++j ) {
double x = from_screen_x( j );
int i = from_viewport_y( fn(x) );
if ( j>0 ) {
line( j-1,lasti, j, i, ch );
}
lasti = i;
}
}
Now we are left with just the business logic. Let's create a cosine functor that will give us a cosine function with a given amplitude and frequency.
struct CosFn {
double amp;
double freq;
double operator()( double x ) {
return amp*cos( freq*x );
}
};
Now we just need to put everything together and plot it all
int main() {
Extents ext{{-1,1},{-1,1}};
Graph<120,20> g{ext};
g.clear();
g.axis();
g.chart( '.', CosFn{1,2} );
g.chart( '^', CosFn{0.75,4} );
g.chart( '*', CosFn{0.5,8} );
g.print();
}
This will produce:
Program stdout
.............|.............
...... | ......
.... ^^^^^^^^^^^ ....
.... ^^^^ | ^^^^ ....
.... ^^^ * ^^^ ....
********* ... ^^^ ****|**** ^^^ ... *********
*** ** ... ^^ ** | ** ^^ ... ** ***
* .**. ^^ ** | ** ^^ .**. *
** ... ** ^^ ** | ** ^^ ** ... **
--*----------...--------*------------^^----------*----------|----------*----------^^------------*--------...----------*-
** ... ** ^^ ** | ** ^^ ** ... *
... * ^^ * | * ^^ * ...
... ** ^^ ** | ** ^^ ** ...
... ^** ** | ** **^ ...
^ ^^^ ********** | ********** ^^^
^^^ ^^^ | ^^^ ^^^
^^^^ ^^^^ | ^^^^ ^^^^
^^^^^^^^^^^ | ^^^^^^^^^^^
|
|
Godbolt link: https://godbolt.org/z/P3Wx1vE7s
I'm currently writing a program where I have to draw three circle shapes from a class(data structure) that will output in the console.
The problem I'm having with my program is that my code compiles, however, the output goes crazy and doesn't draw the circles.
I'm still new to C++ and if anyone can help me out on how to fix this, I would appreciate it.
My Current Code:
////// Circle.h
#include <iostream>
#include <stdlib.h>
#include <sstream>
#include <time.h>
#include <cmath>
using namespace std;
class Circle
{
private:
char type;
int serialNumber = 0;
double radius = 0.0;
double density = 0.0;
public:
Circle(char, int, double);
Circle(char, int, double, double);
~Circle();
void setType(char);
void setSerialNumber(int);
void setRadius(double);
void setDensity(double);
char getType() const;
int getSerialNumber() const;
double getRadius() const;
double getDensity() const;
};
////// Circle.cpp
// #include "Circle.h"
Circle::Circle(char c, int s, double r)
{
type = c;
serialNumber = s;
radius = r;
}
Circle::Circle(char c, int s, double r, double d)
{
type = c;
serialNumber = s;
radius = r;
density = d;
}
Circle::~Circle()
{
cout << "Shapes deleted!" << endl;
}
void Circle::setType(char c)
{
if(c == 'S' || c == 'C')
type = c;
}
void Circle::setSerialNumber(int s)
{
if(s > 0)
serialNumber = s;
}
void Circle::setRadius(double r)
{
if(r > 0)
radius = r;
}
void Circle::setDensity(double d)
{
if(d > 0)
density = d;
}
char Circle::getType() const
{
return type;
}
int Circle::getSerialNumber() const
{
return serialNumber;
}
double Circle::getRadius() const
{
return radius;
}
double Circle::getDensity() const
{
return density;
}
////// main.cpp
// #include "Circle.h"
void drawAll(Circle *[], int);
void drawType(Circle *);
void drawCircle(Circle *);
void drawSpray(Circle *);
void deleteAll(Circle *[], int);
/// For 'C' type the system should display a circle.
/// For 'S' type the system displays a spray pattern just like those used in Microsoft Paint.
int main(int argc, char** argv)
{
const int SIZE = 3;
Circle * arrCircle[SIZE] = {nullptr};
arrCircle[0] = new Circle('C', 1001, 20);
/// Create a Circle whose serial number is 1001 and the radius is 20.
/// Type 'C' indicates Circle type.
arrCircle[1] = new Circle('S', 1002, 25, 30);
/// Create a Spray whose serial number is 1002, the radius is 25, and the density is 30%.
/// Type 'S' indicates Spray type.
arrCircle[2] = new Circle('S', 1003, 40, 80);
/// Create a Spray whose serial number is 1003, the radius is 40, and the density is 80%.
drawAll(arrCircle, SIZE);
/// Draw all shapes. The function uses a for loop to display the circles and sprays in arrCircle.
deleteAll(arrCircle, SIZE);
/// Delete all shapes.
return 0;
}
void drawAll(Circle *arr[], int SIZE)
{
for(int i = 0; i < SIZE; i++)
if(arr[i] != nullptr)
{
cout << "Circle #" << arr[i]->getSerialNumber() << endl;
drawType(arr[i]);
}
}
void drawType(Circle *p)
{
if(p->getType() == 'C')
drawCircle(p);
else if(p->getType() == 'S')
drawSpray(p);
}
void drawCircle(Circle *p)
{
double r = p->getRadius();
int x = 0;
int y = 0;
int rto = 2;
for(int i = 0; i <= 40; i++)
{
for(int j = 0; j <= 40; i++)
{
x = abs(i - 20);
y = abs(j - 20);
r = pow(pow(x, rto) + pow(y, rto), 0.5);
if(19.5 < r && r < 20.5)
cout << "* ";
else
cout << " ";
}
cout << endl;
}
}
void drawSpray(Circle *p)
{
double d = p->getDensity();
int x = 0;
int y = 0;
int rto = 2;
for(int i = 0; i <= 80; i++)
{
for(int j = 0; j <= 80; i++)
{
x = abs(i - 30);
y = abs(j - 30);
d = pow(pow(x, rto) + pow(y, rto), 0.5);
if(19.5 < d && d < 20.5)
cout << "* ";
else
cout << " ";
}
cout << endl;
}
}
void deleteAll(Circle *arr[], int SIZE)
{
for(int i = 0; i < SIZE; i++)
{
if(arr[i] != nullptr)
delete arr[i];
}
}
My Current Output:
Circle #1001
* * * * * * * * *
Expected Output: (example)
Circle #1001
*************
** **
** **
* *
** **
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
** **
* *
** **
** **
*************
Circle #1002
***************
*** ***
** **
* *
* *
** **
* *
* *
* *
** **
* *
* *
* *
* *
* *
* *
** **
* *
* *
* *
** **
* *
* *
** **
*** ***
***************
Circle #1003
*****************
*** ***
** **
* *
** **
* *
* *
* *
** **
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
** **
* *
* *
* *
** **
* *
** **
*** ***
*****************
Here is a simple algorithm it may be helpful with simple mathematics
#include <iostream>
#include <graphics.h>
int main() {
initgraph();
setcolorRGB(23, 143, 44);
int j = 400;
int r = 50; // this is the radius
for (int i = 200;i < 800;i++) {
for (int j = 200;j < 800;j++) {
int p = int(sqrt((pow(i-350,2))+(pow(j-350,2)))); // this is the distance between two points
if (r == p) {
putpixel(j,i);
}
}
}
}
I manage to print out the output for the pattern of stars I wanted but now I want to have a configurable number of stars "*" and automatically calculated corresponding number of rows.
I have tried several ways but the output seems to be off. If there is better way to display the output please guide me.
int i, j, k,l;
k = 1;
l = 11;
for (i = 0; i < 6; i++)
{
for (j = 0; j < k ; j++)
{
cout << "* ";
}
cout << "- ";
k += 2;
for (j = 0; j < l; j++)
{
cout << "* ";
}
l -= 2;
cout << endl;
}
* - * * * * * * * * * * *
* * * - * * * * * * * * *
* * * * * - * * * * * * *
* * * * * * * - * * * * *
* * * * * * * * * - * * *
* * * * * * * * * * * - *
If the number of rows is given, then the resulting number of columns can easily be calculated. Look at your pattern then you will see that the number of necessary coulmns is number of rows times 2 + 1.
Here one possible solution:
#include <iostream>
int main()
{
std::cout << "Enter the number of rows for the pattern: ";
unsigned int numberOfRows{ 0 };
std::cin >> numberOfRows;
// Number of columns is always number of rows * 2 + 1
unsigned int numberOfColumns{ numberOfRows * 2 + 1 };
unsigned int positionOfDash{ 1 };
// Print the pattern
for (unsigned int row = 0; row < numberOfRows; ++row) {
for (unsigned int col = 0; col < numberOfColumns; ++col) {
// Output dash in desired column or else star
std::cout << (col == positionOfDash ? '-' : '*') << ' ';
}
positionOfDash += 2;
std::cout << '\n';
}
return 0;
}
Please note: Of course there are tons of other possible solutions . . .
Is there any other way of doing this? if section of this code make it work but is there any way of using setw() to organize (*) properly?
void showTheater(char theater[][20],int row,int seat)
{
cout << "Seats: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19" << endl;
for (int i = 0; i <= row; i++)
{
for (int j = 0; j <= seat; j++)
{
if (j == 0) {
cout << "Row " << i;
}
else if (i < 10) {
cout << setw(3) << theater[row][seat];
}
else {
cout <<" " << theater[row][seat]<<" ";
}
}
cout << "\n";
}
}
output without writing if section:
Seats: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Row 0 * * * * * * * * * * * * * * * * * * * *
Row 1 * * * * * * * * * * * * * * * * * * * *
Row 2 * * * * * * * * * * * * * * * * * * * *
Row 3 * * * * * * * * * * * * * * * * * * * *
Row 4 * * * * * * * * * * * * * * * * * * * *
Row 5 * * * * * * * * * * * * * * * * * * * *
Row 6 * * * * * * * * * * * * * * * * * * * *
Row 7 * * * * * * * * * * * * * * * * * * * *
Row 8 * * * * * * * * * * * * * * * * * * * *
Row 9 * * * * * * * * * * * * * * * * * * * *
Row 10 * * * * * * * * * * * * * * * * * * * *
Row 11 * * * * * * * * * * * * * * * * * * * *
Row 12 * * * * * * * * * * * * * * * * * * * *
Row 13 * * * * * * * * * * * * * * * * * * * *
Row 14 * * * * * * * * * * * * * * * * * * * *
Row 15 * * * * * * * * * * * * * * * * * * * *
output with if section:
Seats: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Row 0 * * * * * * * * * * * * * * * * * * * *
Row 1 * * * * * * * * * * * * * * * * * * * *
Row 2 * * * * * * * * * * * * * * * * * * * *
Row 3 * * * * * * * * * * * * * * * * * * * *
Row 4 * * * * * * * * * * * * * * * * * * * *
Row 5 * * * * * * * * * * * * * * * * * * * *
Row 6 * * * * * * * * * * * * * * * * * * * *
Row 7 * * * * * * * * * * * * * * * * * * * *
Row 8 * * * * * * * * * * * * * * * * * * * *
Row 9 * * * * * * * * * * * * * * * * * * * *
Row 10 * * * * * * * * * * * * * * * * * * * *
Row 11 * * * * * * * * * * * * * * * * * * * *
Row 12 * * * * * * * * * * * * * * * * * * * *
Row 13 * * * * * * * * * * * * * * * * * * * *
Row 14 * * * * * * * * * * * * * * * * * * * *
Row 15 * * * * * * * * * * * * * * * * * * * *
The key is to use std::setw (in conjunction with std::left) for the index of the row. Here is the code. Note that now the stars are also aligned with the headers. In the posted code, there was also an error on the indices of theater.
void showTheater(char theater[][20], int row, int seat) {
std::vector<int> Seats (seat);
for (int i = 0; i < seat; i++) Seats[i] = i;
std::cout << "Seats:";
for (int i = 0; i < seat; i++) std::cout << std::setw(3) << Seats[i] << " ";
std::cout << "\n";
for (int i = 0; i < row; i++) {
std::cout << "Row " << std::setw(2) << std::left << i << " ";
for (int j = 0; j < seat; j++) {
std::cout << " " << theater[i][i] << " ";
}
std::cout << "\n";
}
}
EDIT: I just discovered that HolyBlackCat already mentioned the way to align the stars. Sorry. At least I also aligned the Headers and suppressed the useless setwfor printing the chars.
I'm trying to print the following pattern:
*
* *
* * *
* *
*
.. but I can't figure it out.
This is the logic that I am following.
i variable is for the row number.
j variable is for the column number.
Using for loops to guide the row number and column number.
I am able to create an increasing triangle pattern using the above logic but can't figure out how to start decreasing the pattern to form a pyramid.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int i;
int j;
for (i = 1; i <= 4; i++)
{
for (j = 1; j < i; j++)
{
cout << "*";
}
cout << endl;
for (i; i <= 6; i++)
{
for (j; j <= 0; j--)
{
cout << "*";
}
cout << endl;
}
}
return 0;
}
I'd really appreciate some guidance to this.
for (i; i <= 6; i++)
It has no effect to mention a variable (i) in the init-statement of a for loop if there is wheter a declaration nor an assignment.
#include <iostream>
int main()
{
int width = 8;
// raising flank:
for (int i = 0; i < width; ++i) {
for (int k = 0; k <= i; ++k) {
std::cout << "* ";
}
std::cout.put('\n');
}
// falling flank:
for (int i = width - 1; i; --i) {
for (int k = 0; k < i; ++k) {
std::cout << "* ";
}
std::cout.put('\n');
}
}
Output:
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * *
* * * * * *
* * * * *
* * * *
* * *
* *
*