draw a sine wave using c? - c

#include <conio.h>
#include <math.h>
#include <graphics.h>
#include <dos.h>
int main() {
int gd = DETECT, gm;
int angle = 0;
double x, y;
initgraph(&gd, &gm, "C:\\TC\\BGI");
line(0, getmaxy() / 2, getmaxx(), getmaxy() / 2);
/* generate a sine wave */
for(x = 0; x < getmaxx(); x+=3) {
/* calculate y value given x */
y = 50*sin(angle*3.141/180);
y = getmaxy()/2 - y;
/* color a pixel at the given position */
putpixel(x, y, 15);
delay(100);
/* increment angle */
angle+=5;
}
getch();
/* deallocate memory allocated for graphics screen */
closegraph();
return 0;
}
This is the program. Why are we incrementing the angle and how this angle is relevant to graph? I changed the value of angle to 0 and the wave became a straight line. I want to know what is happening with this increment.

Why are we incrementing the angle and how this angle is relevant to graph
The sine function takes an angle as argument, typically in radiant. The program implements the angle in degrees, so it's getting scaled to radiant the moment is gets passed to sin().
The sine function is periodical to (repeats itself after) 2*pi or 360 degrees:
+---------+---------+------------+
| angle | sin(angle) |
+---------+---------+ |
| Radiant | Degrees | |
+---------+---------+------------+
| 0 | 0 | 0 |
+---------+---------+------------+
| 1/2*pi | 90 | 1 |
+---------+---------+------------+
| pi | 180 | 0 |
+---------+---------+------------+
| 3/2*pi | 270 | -1 |
+---------+---------+------------+
| 2*pi | 360 | 0 |
+---------+---------+------------+
| 5/2*pi | 450 | 1 |
+---------+---------+------------+
| 3*pi | 540 | 0 |
+---------+---------+------------+
| 7/2*pi | 630 | -1 |
+---------+---------+------------+
| 4*pi | 720 | 0 |
+---------+---------+------------+
| ... | ... | ... |
and so on ...
changed the value of angle to 0 and the wave became a straight line
The result of sin(0) is 0.
For the mathematical derivation you might like to have a look here.

Related

Drawing a bar graph in C

The user should input the elements of an array(maximum 20 of them). The task is to draw a bar graph using |, *, and - by using these elements. A line of minuses should be drawn instead of zero, and * instead of last member of an array. If the number is 3 for example, two | and one * above them should be drawn. The problem that I have with my code is that it sometimes takes too long to execute, draws one instead of two minuses between the array elements, and sometimes doesn't draw the line with minuses.
#include <stdio.h>
int main() {
int n[20];
int i,j,counter=0,input=0,min,max;
printf("Elements of the array: \n");
while(input!=1000){
scanf("%d", &input);
n[counter]=input;
counter++;
}
counter--;
min=n[0];
max=n[0];
for(i=1;i<counter;i++){
if(n[i]>max) max=n[i];
if(n[i]<min) min=n[i];
}
for(i=0;i<max-min+1;i++){
for(j=0;j<2*counter;j++){
if(j%2==0 && n[j/2]==max-i) printf("*");
else if(i==max) printf("-");
else if(j%2==0 && n[j/2]>0 && i<max && n[j/2]>max-i) printf("|");
else if(j%2==0 && n[j/2]<0 && i>max && n[j/2]<max-i) printf("|");
else printf(" ");
}
printf("\n");
}
}// Input:4 -3 7 0 -1 1000 Expected output:
*
|
|
* |
| |
| |
| |
---------*-----
| *
|
*
My output:
*
|
|
* |
| |
| |
| |
------*---
| *
|
*
Input: 5 4 3 2 1 2 3 4 5 Expected output:
* *
| * * |
| | * * | |
| | | * * | | |
| | | | * | | | |
---------------------------
My output:
* *
| * * |
| | * * | |
| | | * * | | |
| | | | * | | | | //

XGetImage takes a lot of time to run

XGetImage takes 3-4 seconds to execute and completely freezes X11
Display *display;
display = XOpenDisplay(NULL);
if (!display) {fprintf(stderr, "unable to connect to display");return 7;}
Window w;
int x,y,i;
unsigned m;
Window root = XDefaultRootWindow(display);
if (!root) {fprintf(stderr, "unable to open rootwindow");return 8;}
//sleep(1);
if(!XQueryPointer(display,root,&root,&w,&x,&y,&i,&i,&m))
{ printf("unable to query pointer\n"); return 9;}
XImage *image;
XWindowAttributes attr;
XGetWindowAttributes(display, root, &attr);
image = XGetImage(display,root,0,0,attr.width,attr.height,AllPlanes,XYPixmap);
XCloseDisplay(display);
if (!image) {printf("unable to get image\n"); return 10;}
In the Xorg log:
[ 13234.693] AUDIT: Thu Jan 7 20:12:13 2016: 3856: client 45 connected from local host ( uid=500 gid=500 pid=12993 )
Auth name: MIT-MAGIC-COOKIE-1 ID: 153
[ 13238.774] AUDIT: Thu Jan 7 20:12:18 2016: 3856: client 45 disconnected
time:
real 0m4.080s
user 0m0.002s
sys 0m0.007s
Ideally I want this function to run in less than 0.1 seconds
XYPixmap is a very specialized format that doesn't have many uses. You should use ZPixmap nearly always.
XYPixmap works plane by plane. What does it mean? Take bit 0 of every pixel, and tightly pack all these bits in an array of unsigned int. That's youir plane 0. Then take bit 1 of every pixel, and pack all these bits in an array. That's your plane 1. Then take bit 2 of every pixel...
Framebuffer
__________________________________________________________________
/
Pixel 0 Pixel 1 Pixel 2
[0][1][2][3][4][5][6][7] [0][1][2][3][4][5][6][7] [0][1][2]....
| | |
| +------------------------+ |
| | |
| | +--------------------------------------------------+
| | |
v v v
[0][0][0]..... \
(Plane 0) |
|
[1][1][1].... | Result
(Plane 1) |
.... |
[7][7][7].... |
(Plane 7) |
/
If your framebuffer is stored like this, which is the case for most modern hardware, that's a lot of bit manipulation!
The picture shows 8 bit pixels, but it's the same for any other depth.
ZPixmap on the other hand takes entire pixels and stuffs them into an array:
Framebuffer
__________________________________________________________________
/
Pixel 0 Pixel 1 Pixel 2
[0][1][2][3][4][5][6][7] [0][1][2][3][4][5][6][7] [0][1][2]....
| | | | | | | | | | | | | | | | | | |
v v v v v v v v v v v v v v v v v v v
[0][1][2][3][4][5][6][7] [0][1][2][3][4][5][6][7] [0][1][2]....
\_____________________________________________________________________
Result
This is simple direct copying, which should be very fast.

How to print vertically in C?

I have to printfs in a loop an I want to print the output in two lines, instead of intermingled on one line.
Like this:
printf("| %-7.2f ", Fahrenheit);
which produces:
| -508.00 | -463.00 | -418.00 | -373.00 | -328.00 | -283.00 |
When I add printf("| %-6d", Celsius); under the printf above, it prints right next to/in the middle of my first printf.
I want the output to be like:
| -508.00 | -463.00 | -418.00 | -373.00 | -328.00 | -283.00 |
| -300 | -275 | -250 | -225 | -200 | -175 | -150 | -125|
instead of the two sets of values being intermingled on the same line.
part of my code:
for(Celsius = CelsiusMin;Celsius <= CelsiusMax; Celsius += CelsiusStep)
{
Fahrenheit = FahrenheitZero + Celsius * CelsiusToFahrenheit;
printf("| %-7.2f ", Fahrenheit);
printf("| %-6d", Celsius);
}
return EXIT_SUCCESS;
}
You can't directly have one sequence of printf() statements writing to line 1 and a second concurrent sequence of printf() statements writing to line 2, so you're going to have to fake it.
You probably need something that builds up the two lines of output, and then prints them when they're ready:
char line1[128];
char line2[128];
char *next1 = line1;
char *next2 = line2;
for (int c = -325; c <= -125; c += 25)
{
double f = (c + 40.0) * (9.0 / 5.0) - 40.0;
next1 += sprintf(next1, "| %-7.2f ", f);
next2 += sprintf(next2, "| %-7d ", c);
}
printf("%s|\n", line1);
printf("%s|\n", line2);
Sample output:
| -553.00 | -508.00 | -463.00 | -418.00 | -373.00 | -328.00 | -283.00 | -238.00 | -193.00 |
| -325 | -300 | -275 | -250 | -225 | -200 | -175 | -150 | -125 |
The conversion formula is simpler than the usual one you see quoted, and is symmetric for converting °F to °C or vice versa, the difference being the conversion factor (9.0 / 5.0) vs (5.0 / 9.0). It relies on -40°C = -40°F. Try it:
C =  0°C; (C+40) = 40; (C+40)*9 = 360; (C+40)*9/5 = 72; (C+40)*9/5-40 = 32°F.
F = 32°F; (F+40) = 72; (F+40)*5 = 360; (F+40)*5/9 = 40; (F+40)*5/9-40 =  0°C.
You might do better with the degrees Celsius as printed as a double too; I kept the integer representation you chose, but made sure the numbers line up on the two lines.
FYI: Absolute zero is -273.15°C, 0K, -459.57°F. So you're attempting to print non-existent temperatures.

how to make gluLookAt and glPerspective to work like glortho?

I don't know how to setup distance
where I should stand to look at my 2d stuff(which at center there is a ball pos:1024/2,768/2)
I use gluLookAt and glPerspective to give my 2d rotated object more 3d feel
anyway here is the code I use with glOrtho:
glMatrixMode ( GL_PROJECTION );
glLoadIdentity();
glOrthof ( 0, 1024, 768, 0, 0, 1000.0f );
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity();
and this is when I try to setup with glPerspective and gluLookAt:
glMatrixMode ( GL_PROJECTION );
glLoadIdentity();
gluPerspective(90,1024/768,0,300);
gluLookAt(1024 * 0.5,768 * 0.5f,-????, 1024 * 0.5,768 * 0.5,0, 0,-1,0);
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity();
Basically I just want those codes that works the same,I am not sure how to setup the fovy value of gluPerspective,and the ??? from gluLookAt,how to project the full size with width 1024,and height 768?
Well glOrtho is supposed to yield a parallel projection, so essentially using gluPerspective is going exactly the other way. If you're hoping to find a special case of gluPerspective that acts like glOrtho, the problem is that the matrices they generate are different in some ways you can't reach - note the bottom right corner, in particular, in what they generate:
glOrtho
| 2 |
|---------- 0 0 t |
|right-left x |
| |
| 2 |
| 0 ---------- 0 t |
| top-bottom y |
| |
| |
| 0 0 -2 |
| -------- t |
| far-near z |
| |
| 0 0 0 1 |
gluPerspective
| f |
| ------ 0 0 0 |
| aspect |
| |
| 0 f 0 0 |
| |
| zFar+zNear 2*zFar*zNear |
| 0 0 ---------- ------------ |
| zNear-zFar zNear-zFar |
| |
| 0 0 -1 0 |
So it's going to be hard to set the 2/(top-bottom) and the bottom row correctly, for starters.
If this line is the core of your issue:
gluLookAt(1024 * 0.5,768 * 0.5f,-????, 1024 * 0.5,768 * 0.5,0, 0,-1,0);
...then just set thee -???? to a positive value indicating the distance to your eye from the center of the scene (OpenGL's positive Z points towards the viewer).

Multiplication algorithm for abritrary precision (bignum) integers

I'm writing a small bignum library for a homework project. I am to implement Karatsuba multiplication, but before that I would like to write a naive multiplication routine.
I'm following a guide written by Paul Zimmerman titled "Modern Computer Arithmetic" which is freely available online.
On page 4, there is a description of an algorithm titled BasecaseMultiply which performs gradeschool multiplication.
I understand step 2, 3, where B^j is a digit shift of 1, j times.
But I don't understand step 1 and 3, where we have A*b_j. How is this multiplication meant to be carried out if the bignum multiplication hasn't been defined yet?
Would the operation "*" in this algorithm just be the repeated addition method?
Here is the parts I have written thus far. I have unit tested them so they appear to be correct for the most part:
The structure I use for my bignum is as follows:
#define BIGNUM_DIGITS 2048
typedef uint32_t u_hw; // halfword
typedef uint64_t u_w; // word
typedef struct {
unsigned int sign; // 0 or 1
unsigned int n_digits;
u_hw digits[BIGNUM_DIGITS];
} bn;
Currently available routines:
bn *bn_add(bn *a, bn *b); // returns a+b as a newly allocated bn
void bn_lshift(bn *b, int d); // shifts d digits to the left, retains sign
int bn_cmp(bn *a, bn *b); // returns 1 if a>b, 0 if a=b, -1 if a<b
I wrote a multiplication algorithm a while ago, and I have this comment at the top. If you have two numbers x and y of the same size (same n_digits) then you would multiply like this to get n, which would have twice the digits. Part of the complexity of the algorithm comes from working out which bits not to multiply if n_digits is not the same for both inputs.
Starting from the right, n0 is x0*y0 and you save off the overflow. Now n1 is the sum of x1*y0 and y1*x0 and the previous overflow shifted by your digit size. If you are using 32 bit digits in 64 bit math, that means n0 = low32(x0*y0) and you carry high32(x0*y0) as the overflow. You can see that if you actually used 32 bit digits you could not add the center columns up without exceeding 64 bits, so you probably use 30 or 31 bit digits.
If you have 30 bits per digit, that means you can multiple two 8 digit numbers together. First write this algorithm to accept two small buffers with n_digits up to 8 and use native math for the arithmetic. Then implement it again, taking arbitrary sized n_digits and using the first version, along with your shift and add method, to multiply 8x8 chunks of digits at a time.
/*
X*Y = N
x0 y3
\ /
\ /
X
x1 /|\ y2
\ / | \ /
\ / | \ /
X | X
x2 /|\ | /|\ y1
\ / | \ | / | \ /
\ / | \|/ | \ /
X | X | X
x3 /|\ | /|\ | /|\ y0
\ / | \ | / | \ | / | \ /
\ / | \|/ | \|/ | \ /
V | X | X | V
|\ | /|\ | /|\ | /|
| \ | / | \ | / | \ | / |
| \|/ | \|/ | \|/ |
| V | X | V |
| |\ | /|\ | /| |
| | \ | / | \ | / | |
| | \|/ | \|/ | |
| | V | V | |
| | |\ | /| | |
| | | \ | / | | |
| | | \|/ | | |
| | | V | | |
| | | | | | |
n7 n6 n5 n4 n3 n2 n1 n0
*/
To do A*b_j, you need to do the grade school multiplication of a bignum with a single digit. You end up having to add a bunch of two-digit products together:
bn *R = ZERO;
for(int i = 0; i < n; i++) {
bn S = {0, 2};
S.digits[0] = a[i] * b_j;
S.digits[1] = (((u_w)a[i]) * b_j) >> 32; // order depends on endianness
bn_lshift(S, i);
R = bn_add(R, S);
}
Of course, this is very inefficient.

Resources