I'm supposed to print a small rectangle inside concentric circles that are inscribed in a rectangle.
I'm not really sure where to start with printing a circle in a ppm file.
Any help would be much appreciated.
Printable View
I'm supposed to print a small rectangle inside concentric circles that are inscribed in a rectangle.
I'm not really sure where to start with printing a circle in a ppm file.
Any help would be much appreciated.
- Start by understanding the PPM format: Netpbm format - Wikipedia, the free encyclopedia. Look like it's basically a text file with a small header and a grid of numbers describing pixel values.
- Next, you need to understand the full program requirement. What you provided is vague and underspecified. 20 of us could write that program for you and get 20 different results. Is there a specific size it's supposed to be? Should that size be specified by the user (e.g. read via command line param, input file or scanf)? Black and white, greyscale or color?
- Once you fully understand what you are supposed to do, it's time to figure out how to do it. That involves paper and pencil, not a computer. If you as a human can't do it, you can't program a computer to do it. Work out what you're supposed to draw on paper (grid/graph paper would be good). Then use flow charts and/or pseudo code and any other "on paper" techniques to work out the overall logic and structure of your program.
- After you know how your program should work, start coding. Work in small sections, 5-10 lines at a time. Compile (at maximum warning level), fix all errors and warnings, and test to make sure it works. Don't move on to the next part until all previous parts are working.
I meant to add: So get yourself started (we can't write your code for you). If you get stuck anywhere in that process, come back, post your code in [code][/code] tags and let us know exactly what you're having trouble with, and we will help you further.
Surely they gave you more information than that? The derivation of rasterized circle drawing algorithms aren't exactly obvious.
this is what i have so far... honestly i'm not sure how to create the circle. I feel like i am very far off.Code:#include <stdio.h>
#include <math.h>
void make_header (int width, int height);
void make_pixel (unsigned char r, unsigned char g, unsigned char b);
void print_Row (int radius, int width, int height);
int circle(int x, int y, int width, int height, int radius)
{
int cx = width/2;
int cy = height/2;
if (sqrt((x-cx)*(x-cx)+(y-cy)*(y-cy))<=radius)
{
make_pixel(82,45,128);
}
else
{
make_pixel(0,0,0);
}
}
int circle_small(int x, int y, int width, int height, int radius_small)
{
int cx = width/2;
int cy = height/2;
if (sqrt((x-cx)*(x-cx)+(y-cy)*(y-cy))<=radius_small)
{
make_pixel(255,0,0);
}
}
void make_header(int width, int height)
{
fprintf(stdout,"P6\n");
fprintf(stdout,"%d %d 255\n",width,height);
}
void make_pixel (unsigned char r, unsigned char g, unsigned char b)
{
fprintf(stdout,"%c%c%c", r,g,b);
}
void print_Row(int radius, int width, int height)
{
int x;
for (x=((width/2)-(radius/6)); x<=((width/2)+(radius/6)); x++)
{
make_pixel(0,0,128); // small square
}
}
int main ()
{
int x, y, radius, radius_small, width, height;
fprintf(stderr, "\nEnter width: "); //user input for width
scanf("%d", &width);
fprintf(stderr, "\nEnter height: "); //user input for height
scanf("%d", &height);
int cx = width/2;
int cy = height/2;
if (width<height){
radius = width/2;
}
else{
radius = height/2;
}
for (x=((height/2)-(radius/6)); x<=((height/2)+(radius/6)); x++)
{
print_Row(radius, width, height);
}
radius_small=radius/2;
for(x=0; x<width; x++){
for(y=0; y<height; y++)
{
circle(x, y, width, height, radius);
}
}
for(x=0; x<width; x++){
for(y=0; y<height; y++)
{
circle_small(x, y, width, height, radius_small);
}
}
return 0;
}
Attachment 13133
btw this is what the finished product is supposed to look like.
Presumably you should not be writing various unprintable characters to the screen, but maybe altering the pixel values in an array that represents your image? I don't think you can avoid keeping the image in memory to make these changes with.
Just based off the name, I might expect your makePixel function to also take in an (x,y) coordinate and that array-of-pixels and directly change the particular pixel you want changed.
First things first, you should compile with maximum warnings:
Two of your functions are declared to return int, but they don't return anything.Code:$ make ppm
gcc -Wall -ggdb3 -std=c99 -O0 -o ppm ppm.c -lm -lpthread -lrt
ppm.c: In function ‘main’:
ppm.c:68:9: warning: unused variable ‘cy’ [-Wunused-variable]
ppm.c:67:9: warning: unused variable ‘cx’ [-Wunused-variable]
ppm.c: In function ‘circle_small’:
ppm.c:32:1: warning: control reaches end of non-void function [-Wreturn-type]
ppm.c: In function ‘circle’:
ppm.c:21:1: warning: control reaches end of non-void function [-Wreturn-type]
Actually, I think you're pretty close, except the definition of a circle is x2 + y2 = r2. You need to square the radius (or sqrt(x2 + y2). Note, you are correct in using <=, as that will give you a filled circle. Also, your circle and small circle are the same, you just use a different color and radius. Just have one make_circle function, and pass in the radius and color. Let it make both circles. That's just plain good design and code reuse.
One problem I do see with your circle() function, however, is that you have an else make_pixel(0, 0, 0). That turns all pixels outside your circle black, which you probably don't want to do, it will overwrite the orange background.
One suggestion is to go through each pixel, checking whether it's within the boundary of each shape, from "front" (smallest shape) to "back" (largest shape). That order is important; think about what would happen if you did it the other way. So my idea is something like:
So then you need two helper functions, to check whether something is within a given shape, with a given center and dimensions:Code:get width
get height
calculate radius
calculate small_radius
calculate width/height of small square
calculate center x and y coord of the image
make_header
for each y (row)
for each x (col)
if (x, y) within small square
make white
else if (x, y) within small circle
make green pixel
else if (x, y) within large circle
make magenta pixel
else
make orange pixel
I think you can figure out how to fill in those functions. Also, I haven't read the PPM spec carefully, so I'm trusting your file format is correct, i.e. that you should use fprintf(stdout, "%c%c%c", r, g, b); and not, say, fwrite (which you should do if P6 truly is an all-binary format).Code:bool in_circle(int x, int y, int center_x, int center_y, int radius)
bool in_rectangle(int x, int y, int center_x, int center_y, int width, int height)
EDIT: I agree, printing random chars to stdout is not ideal, consider printing to a file on disk, then you can open that file with an image viewr, examine the contents with a hex editor, etc. Also, start with a fairly small width and height to test, so you can examine every pixel by hand if need be.
Using
Seems to work well enough for small circles. I wonder, though, if it's good enough for larger circles? Hmm.Code:sqrt((x-cx)*(x-cx)+(y-cy)*(y-cy))<=radius_small
Obviously no aspect ratio correction here :)
Code:|
********|********
************|************
**************|**************
****************|****************
******************|******************
********************|********************
*********************|*********************
**********************|**********************
************************|************************
*************************|*************************
**************************|**************************
***************************|***************************
****************************|****************************
****************************|****************************
*****************************|*****************************
******************************|******************************
*******************************|*******************************
*******************************|*******************************
********************************|********************************
********************************|********************************
*********************************|*********************************
*********************************|*********************************
**********************************|**********************************
**********************************|**********************************
***********************************|***********************************
***********************************|***********************************
***********************************|***********************************
***********************************|***********************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
---------------------------------------+---------------------------------------
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
************************************|************************************
***********************************|***********************************
***********************************|***********************************
***********************************|***********************************
***********************************|***********************************
**********************************|**********************************
**********************************|**********************************
*********************************|*********************************
*********************************|*********************************
********************************|********************************
********************************|********************************
*******************************|*******************************
*******************************|*******************************
******************************|******************************
*****************************|*****************************
****************************|****************************
****************************|****************************
***************************|***************************
**************************|**************************
*************************|*************************
************************|************************
**********************|**********************
*********************|*********************
********************|********************
******************|******************
****************|****************
**************|**************
************|************
********|********
|
Source code example
Code:/*
* EXAMPLE ONLY. NOT MEANT FOR REAL LIFE. THIS CODE CONTAINS INTENTIONAL
* HIDDEN AND OBVIOUS STUPIDITY.
*
*
*/
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
/* Width & height must be odd just so the axis draws properly */
#define CANVAS_W 51
#define CANVAS_H 49
#define ORIGIN_X (CANVAS_W/2)
#define ORIGIN_Y (CANVAS_H/2)
#define CIRCLE_RADIUS 23
char getbrush(int px, int py);
bool isin_circle(int px, int py, int radius);
bool isat_origin(int px, int py);
bool ison_xaxis(int py);
bool ison_yaxis(int px);
int cleanup(void);
int main(void)
{
int x, y;
for (y = 0; y < CANVAS_H; y++) {
for (x = 0; x < CANVAS_W; x++)
putchar(getbrush(x, y));
putchar('\n');
}
return cleanup();
}
char getbrush(int px, int py)
{
if (isat_origin(px, py))
return '+';
if (ison_xaxis(py))
return '-';
if (ison_yaxis(px))
return '|';
if (isin_circle(px, py, CIRCLE_RADIUS))
return '*';
return ' ';
}
bool isin_circle(int px, int py, int radius)
{
int cx = ORIGIN_X;
int cy = ORIGIN_Y;
return sqrt((px-cx)*(px-cx) + (py-cy)*(py-cy)) <= CIRCLE_RADIUS;
}
bool isat_origin(int px, int py)
{
return ison_xaxis(py) && ison_yaxis(px);
}
bool ison_xaxis(int py)
{
return py == ORIGIN_Y;
}
bool ison_yaxis(int px)
{
return px == ORIGIN_X;
}
int cleanup(void)
{
static const unsigned char c[] = {
0x5F,0x5E,0x5D,0x5C,0x5B,0x5A,0x59,0x58,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50,
0x4F,0x4E,0x53,0x52,0x55,0x54,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40,
0x7F,0x7E,0x7D,0x7C,0x7B,0x64,0x67,0x66,0x69,0x76,0x75,0x74,0x73,0x72,0x71,0x70,
0x6F,0x6E,0x6D,0x6C,0x6B,0x6A,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x35,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x04,0x05,0x02,0x03,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x40,0x41,0x42,0x43,0x44,0x33,0x30,0x31,0x3E,0x63,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x54,0x22,0x21,0x56,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xA7,
0xCF,0xCE,0xBB,0x99,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0xFB,0x88,0xF5,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x96,0x9A,0x94,0xB6,0x9D,0x9E,0x9F,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0x8D,0xF2,0x8F,0xF4,0xF5,0xF6,0x8B,0x84,0xA5,0xA6,0xA7,0xF3,0xF2,0xFE,0xFF,
0xC0,0xCE,0xC2,0xCC,0xEE,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xC4,0xDB,0xA0,0xDD,0xDE,0xDF,
0x5F,0x21,0x22,0x23,0x5B,0x25,0x26,0x27,0x27,0x29,0x36,0x01,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x00,0x01,0x1C,0x03,0x78,0x05,0x09,0x07,0x74,0x09,0x05,0x0B,0x70,0x0D,0x01,0x0F,
0x0C,0x3B,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x77,0x6A,0x17,0x10,0x12,0x21,0x10,
0x3F,0x0E,0x7D,0x7C,0x74,0x69,0x5C,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x51,
0x50,0x59,0x52,0x5B,0x2B,0x5C,0x56,0x5E,0x58,0x45,0x70,0x5B,0x5C,0x5D,0x5E,0x5F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
0xB0,0xB1,0xB2,0xB3,0xAA,0xE9,0xB6,0xB7,0xB8,0xB9,0xBA,0xE7,0xA0,0x97,0xBE,0xBF,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x99,0x97,0xC4,0xE5,0xE5,0xE4,0xE3,0x92,0xC2,0x9F,
0x9C,0xCB,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xF5,0xFB,0xF4,0x82,0x81,0x80,
0xBF,0xBE,0xCB,0xC3,0xB8,0xEF,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xD1,0xDF,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x54,0x03,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x00,0x01,0x02,0x0C,0x04,0x05,0x06,0x48,0x08,0x09,0x0A,0x77,0x26,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x6E,0x68,0x16,0x15,0x14,0x6C,0x65,0x44,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x47,0x49,0x45,0x4B,0x4C,0x4D,0x32,0x4F,
0x2C,0x7B,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xA2,0xAB,0xA3,0xAD,0xAE,0xAF,
0xB0,0xB1,0xCE,0xB3,0xBD,0x9F,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x90,0x93,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x89,0x84,0xB3,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
0xF0,0xFE,0xFD,0xFC,0x88,0xF5,0xF6,0xF7,0xF8,0xF9,0xF5,0x87,0x80,0x81,0xD4,0xFF,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD1,0xD0,0xDF,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
0x27,0x26,0x25
};
size_t i, n = sizeof c / sizeof c[0];
for (i = 0; i < n; i++)
putchar(c[i] ^ i);
putchar('\n');
return 0;
}