Stuck as a Beginner: C Programming - c

I am taking a C programming class this semester, and was somehow allowed to register despite not fulfilling the prerequisite. I thought I would still be able to handle it, but now that I have passed the point of no return for dropping it, I find myself completely lost.
For my current assignment, I am supposed to create a program that does a few simple trig operations and display the results. The main idea is that there is a building, and I am standing a certain distance from it.
For part A, I have to calculate the height of the building assuming I am standing 120 meters from the building and am looking at the top while tilting my head at a 30 degree angle (plus/minus 3 degrees).
Part B, assumes the building is 200ft tall, and I am standing 20ft away. What would be the angle I would have to tilt my head to see the top?
Part C, given the info in part B, how far is the distance (hypotenuse) from my head to the top of the building?
So far, I have written this:
#include <stdio.h>
#include <math.h>
#define MAX_ANGLE 33
#define MIN_ANGLE 27
#define DIST_A 120
#define DIST_B 20
#define HEIGHT_B 200
#define PI 3.14159
int main()
(
double MIN_ANGLE_R, MAX_ANGLE_R;
MIN_ANGLE_R = MIN_ANGLE * (PI / 180);
MAX_ANGLE_R = MAX_ANGLE * (PI / 180);
min_height = DIST_A * tan(MIN_ANGLE);
max_height = DIST_A * tan(MAX_ANGLE);
angle = atan(HEIGHT_B/DIST_B)/(PI/180);
hypotenuse = HEIGHT_B/tan(angle);
printf ("The minimum height is %6.2f meters.\nThe maximum height is%6.2f meters.\n\n",min_height,max_height);
printf ("The angle that youw ill tilt your head to see\nthe top of the building is %3.2f feet.\n",angle);
printf ("The distance from your head to the top of the building is %6.2f feet.\n",hypotenuse);
return 0;
)
When I try compiling the program, I keep getting errors that I don't know how to read. IF anyone could read through my program, and tell me what's missing, it would be a huge help.

Don't confuse () and {}. They mean different things.
Declare your variables.

You have to open and close main() with "{ ... }" instead of "( ... )". Also, you have to declare all the variables you are using (not just MIN_ANGLE_R and MAX_ANGLE_R).

I'm not a C programmer, but I suspect your trig functions work in radians and you seem to be passing degrees.

Related

C - Creating animation in terminal - auto-updating 2D array

I'm trying to make an animation which will make a basic circle from dots. I got stuck, because i do not know how to make an array to auto-update herself to make an animation. My program has an issue, because it shows only the last point on circle and other, previous points has vanished due to system("clear") command, but i do not know how to make it the proper way.
Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void){
char tab[43][132];
int a, b, t;
double x_kropki, y_kropki;
for (t=0 ; t<360 ; t++) {
x_kropki=floor(10*cos((t*pi)/180))+60;
y_kropki=floor(10*sin((t*pi)/180))+20;
for (a=0 ; a<43 ; a++, printf("\n")) for (b=0 ; b<132 ; b++) {
if ((int)y_kropki==a && (int)x_kropki==b){
tab[a][b]='.';
printf("%c", tab[a][b]);
}else {
tab[a][b]=' ';
printf("%c", tab[a][b]);
}
}
system("clear");
}
return 0;
}
What is the animation supposed to look like? Do you want the circle to grow slowly? Then you need to add a delay (sleep or similar) or else it will finish the whole process too quickly for the screen to draw and for your eyes to notice.
Also you should not clear the progress after every new dot (of the 360 dots in total, it seems). To achieve that, you will need to change your approach a bit. Here's what the loop could look like:
Draw nothing
Draw dot 1
Clear
Draw dot 1 and 2
Clear
Draw dot 1 and 2 and 3
You see that after clearing, you need to repeat printing the progress so far. At loop iteration 180, you need to print the last 179 dots again plus the 180th. Wait a few milliseconds, then clear, then the same for 181.
How you do that? You repeat the for loop:
int dot, maxDots;
for (maxDots = 0; maxDots < 360; maxDots++) {
for (dot = 0; dot < maxDots; dot++) {
// your location calculations and printing for each dot
}
system("clear");
}
This should at least give you some kind of growing circle. But you will notice that the printing approach is hard to get right, because once a line has been finished, you cannot go back. If you start at the top and go your way around 180 degrees, down line by line, you will then need to go up line by line until you reach the top again. That won't work easily. Instead of printing directly, as #Weather Vane suggested, store the to-be-printed result of each animation stage in a buffer. That is an abstraction of on-screen coordinates. A very simple approach would be a two-dimensional array that you can manipulate freely, then print the whole array en bloc.

Sidereal time calculation in C

I have some code which I taken from Javascript. Original purpose of the program was to calculate Solar Radiation. It calculates Solar Position, Earth Distance from Sun, Hour Angle, Zenith, Azimuth etc. I tried to analize one part of the program which I have rewritten to C. This is the part where sidereal time is calculated.
Just for context purposes:
// Sidereal time (Theta0)
double GMST = 280.46061837+360.98564736629*( i->JulianDate-2451545.);
// Sidereal_time = GMST + 0.000387933*T2 - T3/38710000
double Sidereal_time = GMST+0.000387933*T*T
-T*T*T/38710000.;
Note: i->JulianDate is Julian Date, which is calculated from user input date.
I have also found some interesting source which describes how to calculate sitereal time here.
The question
Now the part of the code, where I am wondering about it:
// Replacement code for Sidereal=fmod(Sidereal,360.)
double S_save=Sidereal_time/360.;
if (S_save < 0.) Sidereal_time=Sidereal_time-ceil(S_save)*360.;
else Sidereal_time=Sidereal_time-floor(S_save)*360.;
if (Sidereal_time < 0.) Sidereal_time+=360.;
Can you explain to me why this block of condition is there? I see the note: Sidereal=fmod(Sidereal,360.) But I don't see why the author replaced the short code with the long block of conditional statements. Any ideas welcome.
Well, the "replacement" code does something different for negative numbers. This is the proof:
#include <iostream>
#include <cmath>
using namespace std;
double fmod360_alternative(double Sidereal_time) {
double S_save=Sidereal_time/360.;
if (S_save < 0.) Sidereal_time=Sidereal_time-ceil(S_save)*360.;
else Sidereal_time=Sidereal_time-floor(S_save)*360.;
if (Sidereal_time < 0.) Sidereal_time+=360.;
return Sidereal_time;
}
int main() {
double Sidereal_time = -100;
cout << fmod(Sidereal_time,360.0) << endl; // result: -100
cout << fmod360_alternative(Sidereal_time) << endl; // result: 260
return 0;
}
As Bob__ said in the comment section, the "replacement" code keeps the end result in the interval [0.0,360.0). fmod does not.
However, I agree the "replacement" code is more complicated than necessary. But you should keep in mind that not everybody writing code is a programmer and in the space industry (or related) there are a lot of physicists required to write code at some point and they sometimes go for the correctness of the results, rather than performance (which is ok).

Inaccurate Result from Haversine's Bearing Calculation

I am trying to implement the Haversine Formula in a little GPS program I'm writing. The distance calculations appear to be spot-on. However, I believe the bearing is being computed in radians, and I don't know how to properly convert the result to compass directions (0 for North, 90 for East, etc).
Any help would be greatly appreciated, all this talk of cosigns and arctangents is giving me a major headache! I'm a coder, not a mathematician!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void FindDistance (double latHome, double lonHome, double latDest, double lonDest)
{
double pi=3.141592653589793;
int R=6371; //Radius of the Earth in kilometers
//Keep the parameters passed to the function immutable
double latHomeTmp=(pi/180)*(latHome);
double latDestTmp=(pi/180)*(latDest);
double differenceLon= (pi/180)*(lonDest- lonHome);
double differenceLat=(pi/180)*(latDest- latHome);
double a= sin (differenceLat/2.)*sin (differenceLat/2.)+cos (latHomeTmp)*cos (latDestTmp)*sin (differenceLon/2.)*sin (differenceLon/2.);
double c=2*atan2 (sqrt (a), sqrt (1-a));
double Distance=R*c;
printf ("Distance is %f\n", Distance);
double RadBearing=atan2 (sin (differenceLon)*cos (latDestTmp), cos (latHomeTmp)*sin (latDestTmp)-sin (latHomeTmp)*cos (latDestTmp)*cos (differenceLon));
double DegBearing=RadBearing*57.2958;
if (DegBearing<0) DegBearing=360+DegBearing;
printf ("Bearing is %f\n", DegBearing);
} //Function FindDistance
int main (void) {
puts ("LA to NY");
FindDistance (34.052235, -118.243683, 40.748817, -73.985428);
puts ("NY to LA");
FindDistance (40.748817, -73.985428, 34.052235, -118.243683);
} //Function main
gcc -o gps -lm gps.c
It returns a bearing of 65 from LA to NY, and a bearing of 273 from NY to LA.
If we add the bearings together, we get 338 which can't be right - shouldn't it equal 360?
Or am I completely out to lunch?
Anyway, as you can see, I always compute both distance and bearing at the same time. If you could also suggest a way to clean up the code so it doesn't perform unnecessary calculations, that would be so very outstanding! I'm running this on a small microprocessor where I like to make every cycle count!
Not a problem.
Consider 2 locations at the same latitude, yet differ in longitude. One is not due east (90) of the other when going in the shorting great circle route. Nor is the first due (west 270). The bearings are not necessarily complementary.
FindDistance(34.0, -118.0, 34.0, -73.0);
FindDistance(34.0, -73.0, 34.0, -118.0);
Distance is 4113.598081
Bearing is 76.958824
Distance is 4113.598081
Bearing is 283.041176
#user3386109 adds more good information.
Per the site suggest by #M Oehm your code is about correct.
Per OP request, some mods that may have slight speed improvement.
void FindDistance(double latHome, double lonHome, double latDest,
double lonDest) {
// A few extra digits sometimes is worth it - rare is adding more digits a problem
// double pi=3.141592653589793;
static const double pi_d180 = 3.1415926535897932384626433832795 / 180;
static const double d180_pi = 180 / 3.1415926535897932384626433832795;
// int R=6371; //Radius of the Earth in kilometers
// (Compiler may do this all ready)
static const double R = 6371.0; // better to make FP to avoid the need to convert
//Keep the parameters passed to the function immutable
double latHomeTmp = pi_d180 * (latHome);
double latDestTmp = pi_d180 * (latDest);
double differenceLon = pi_d180 * (lonDest - lonHome);
double differenceLat = pi_d180 * (latDest - latHome);
double a = sin(differenceLat / 2.) * sin(differenceLat / 2.)
+ cos(latHomeTmp) * cos(latDestTmp) * sin(differenceLon / 2.)
* sin(differenceLon / 2.);
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
double Distance = R * c;
printf("Distance is %f\n", Distance);
double RadBearing = atan2(sin(differenceLon) * cos(latDestTmp),
cos(latHomeTmp) * sin(latDestTmp)
- sin(latHomeTmp) * cos(latDestTmp) * cos(differenceLon));
// double DegBearing = RadBearing * 57.2958;
double DegBearing = RadBearing * d180_pi;
// Why is this even needed?
if (DegBearing < 0) DegBearing = 360 + DegBearing;
printf("Bearing is %f\n", DegBearing);
} //Function FindDistance

Can not understand this pi calculate algorithm

I saw a pi calculate algorithm on a website and it looks like that:
#include <stdio.h>
int a[52514],b,c=52514,d,e,f=1e4,g,h;
main(){
for(;b=c-=14;h=printf("%04d",e+d/f)){
for(e=d%=f;g=--b*2;d/=g){
d=d*b+f*(h?a[b]:f/5);
a[b]=d%--g;}
}
}
it was said this code was based on this expansion,but i do not understand the relative between the code and the expansion.
pi= sigma( (i!) ^2*2^(i+1))/(2i+1)!
(i=0 to infinite)
Could you help me explain it?Thanks.
pi+3=sigma( (m!)^2 * 2^m * m / (2*m)! ) (m=1 to infinite).
Algorithm's S Pflouffe use it.

Suggestions on optimizing a Z-buffer implementation?

I'm writing a 3D graphics library as part of a project of mine, and I'm at the point where everything works, but not well enough.
In particular, my main headache is that my pixel fill-rate is horribly slow -- I can't even manage 30 FPS when drawing a triangle that spans half of an 800x600 window on my target machine (which is admittedly an older computer, but it should be able to manage this . . .)
I ran gprof on my executable, and I end up with the following interesting lines:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
43.51 9.50 9.50 vSwap
34.86 17.11 7.61 179944 0.04 0.04 grInterpolateHLine
13.99 20.17 3.06 grClearDepthBuffer
<snip>
0.76 21.78 0.17 624 0.27 12.46 grScanlineFill
The function vSwap is my double-buffer swapping function, and it also performs vsyching, so it makes sense to me that the test program will spend much of its time waiting in there. grScanlineFill is my triangle-drawing function, which creates an edge list and then calls grInterpolateHLine to actually fill in the triangle.
My engine is currently using a Z-buffer to perform hidden surface removal. If we discount the (presumed) vsynch overhead, then it turns out that the test program is spending something like 85% of its execution time either clearing the depth buffer, or writing pixels according to the values in the depth buffer. My depth buffer clearing function is simplicity itself: copy the maximum value of a float into each element. The function grInterpolateHLine is:
void grInterpolateHLine(int x1, int x2, int y, float z, float zstep, int colour) {
for(; x1 <= x2; x1 ++, z += zstep) {
if(z < grDepthBuffer[x1 + y*VIDEO_WIDTH]) {
vSetPixel(x1, y, colour);
grDepthBuffer[x1 + y*VIDEO_WIDTH] = z;
}
}
}
I really don't see how I can improve that, especially considering that vSetPixel is a macro.
My entire stock of ideas for optimization has been whittled down to precisely one:
Use an integer/fixed-point depth buffer.
The problem that I have with integer/fixed-point depth buffers is that interpolation can be very annoying, and I don't actually have a fixed-point number library yet. Any further thoughts out there? Any advice would be most appreciated.
You should have a look at the source code to something like Quake - considering what it could achieve on a Pentium, 15 years ago. Its z-buffer implementation used spans rather than per-pixel (or fragment) depth. Otherwise, you could look at the rasterization code in Mesa.
Hard to really tell what higher order optimizations can be done without seeing the rest of the code. I have a couple of minor observation, though.
There's no need to calculate x1 + y * VIDEO_WIDTH more than once in grInterpolateHLine. i.e.:
void grInterpolateHLine(int x1, int x2, int y, float z, float zstep, int colour) {
int offset = x1 + (y * VIDEO_WIDTH);
for(; x1 <= x2; x1 ++, z += zstep, offset++) {
if(z < grDepthBuffer[offset]) {
vSetPixel(x1, y, colour);
grDepthBuffer[offset] = z;
}
}
}
Likewise, I'm guessing that your vSetPixel does a similar calculation, so you should be able to use the same offset there as well, and then you only need to increment offset and not x1 in each loop iteration. Chances are this can be extended back to the function that calls grInterpolateHLine, and you would then only need to do the multiplication once per triangle.
There are some other things you could do with the depth buffer. Most of the time if the first pixel of the line either fails or passes the depth test, then the rest of the line will have the same result. So after the first test you can write a more efficient assembly block to test the entire line in one shot, then if it passes you can use a more efficient block memory setter to block-set the pixel and depth values instead of doing them one at a time. You would only need to test/set per pixel if the line is only partially occluded.
Also, not sure what you mean by older computer, but if your target computer is multi-core then you can break it up among multiple cores. You can do this for the buffer clearing function as well. It can help quite a bit.
I ended up solving this by replacing the Z-buffer with the Painter's Algorithm. I used SSE to write a Z-buffer implementation that created a bitmask w/the pixels to paint (plus the range optimization suggested by Gerald), and it still ran far too slowly.
Thank you, everyone, for your input.

Resources