0

I am working on C graphics program, where I will ask for Projection Angle from end user and then will use that angle to launch the rocket from earth (circle) surface.

But I am not able to do so.

Here what I found on google:

x1 = x + cos(angle) * distance;
y1 = y + sin(angle) * distance;

where x1 y1 are the new pixel position for object.

I tried this but it doesn't seem like working. Also I want rocket to move constantly till the end of screen, but the above code will directly print the object from position A to position B.

Complete Program Code

#include        <stdio.h>
#include        <conio.h>
#include     <graphics.h>
#include          <dos.h>
#include         <math.h>
#include       <stdlib.h>
#include     <iostream.h>

#define cld cleardevice()

int _moonRadius = 20, _earthRadius = 40, _marsRadius = 25;

void mars () {
    setfillstyle(9, BROWN);
    setcolor(BROWN);
    circle(getmaxx() - 25, 50, _marsRadius);
    floodfill(getmaxx() - 27, 52, BROWN);
}

void moon () {
    setfillstyle(9, WHITE);
    setcolor(WHITE);
    circle(getmaxx()/2, getmaxy()/2, _moonRadius);
    floodfill(getmaxx()/2, getmaxy()/2, WHITE);

    // Moon's gravitational area
    setfillstyle(SOLID_FILL, DARKGRAY);
    setcolor(DARKGRAY);
    circle(getmaxx()/2, getmaxy()/2, _moonRadius * 5);
}

void earth () {
    setfillstyle(9, GREEN);
    setcolor(GREEN);
    circle(40, getmaxy() - 100, _earthRadius);
    floodfill(42, getmaxy() - 102, GREEN);
}

void rocket (int x, int y) {
    setcolor(WHITE);
    rectangle(x, y - 105, x + 70, y - 95);
}

void rocket_clear (int x, int y) {
    setcolor(BLACK);
    rectangle(x, y - 105, x + 70, y - 95);
}

void main () {
    clrscr();
    int angle, speed;

    printf("Please provide input parameters.");
    printf("Enter projection angle (range from 5 to 90)\n");
    scanf("%d", &angle);

    printf("Enter projection speed (range from 10 to 100)\n");
    scanf("%d", &speed);

    int gd=DETECT, gm, i, j, k;
    initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");

    // Planets and rocket
    mars();
    moon();
    earth();
    rocket(80, 550); // let say initial pixel position x = 80, y = 550
    
    // Moving the rocket
    // Right now its only moving towards horizontal line, with speed implementation
    // Now here I want to implement the angle of projection
    for (i = 81; i < getmaxx() + 100; i++) {
        // Also I am not sure about this loop's final range, should it go to getmaxx() or some other range
        rocket(i, 550);
        rocket_clear(i - 1, 550); // 550 is hard coded right now, so rocket will move only horizontally
        delay(500 / speed);
    }
    getch();
}

Need your help guys, please.

(For reference: you can also think of a moving bullet from killer position to the position of person with some angle)

Thanks :)

genpfault
  • 51,148
  • 11
  • 85
  • 139
Shivam Verma
  • 905
  • 1
  • 8
  • 20
  • 2
    Are you giving the angle values as arguments to the `sin` and `cos` functions in *radians*? – Adrian Mole Jun 27 '21 at 04:10
  • 1
    Is it WinBGI graphics? Can you provide the full code so that the readers can proceed with further debugging? – Programmer Hobbyist Jun 27 '21 at 04:17
  • The distance must increase at the rate of speed like, 0, 0+d, 0+2d....... in an AP every second. This will give the effect of your rockect moving continously ...... – Psychopathic Azula Jun 27 '21 at 04:20
  • @AdrianMole thanks for the reference link of "Adding Urgent" in the question I will keep in mind buddy. And yes I am passing the angle values as argument to the `sin` and `cos` – Shivam Verma Jun 27 '21 at 04:32
  • @ProgrammerHobbyist this is not winBGI graphics, this is TurboC++ graphics using `graphics.h` library – Shivam Verma Jun 27 '21 at 04:34
  • @PsychopathicAzula So you are saying the above code should run inside a loop where in each iteration distance will increase based on speed. – Shivam Verma Jun 27 '21 at 04:39
  • @ShivamVerma yes – Psychopathic Azula Jun 27 '21 at 04:44
  • I know. The graphics.h contains WinBGI graphics implementation. – Programmer Hobbyist Jun 27 '21 at 04:47
  • Can you edit the question and add the code? I mean, full code. – Programmer Hobbyist Jun 27 '21 at 04:48
  • Be advised that the equations you quote are for baseballs, footballs and rocks.   They assume that the Earth is flat.   If you want to simulate a rocket going into space, you need different equations.  P.S. Please read Adrian Mole’s second comment again; I fear that you missed the point. – Scott - Слава Україні Jun 27 '21 at 05:02
  • @AdrianMole I am passing the angle directly to the sin cos, I mean I am not converting it into Radians. – Shivam Verma Jun 27 '21 at 05:24
  • @Scott do you have any idea man, what will be the equation look like for rocket launching scenario? – Shivam Verma Jun 27 '21 at 05:25
  • StackOverflow is not a free code writing or translation service. We're more than happy to help once you've made an effort to solve the problem yourself and run into difficulties. When that happens, you can explain the problem you're having, include the relevant portions of your code (and any original code) in the form of a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), and ask a specific question related to that code, and we'll try to help. – fpiette Jun 27 '21 at 05:26
  • Much more complicated. Search for “orbital mechanics”, or something like that. – Scott - Слава Україні Jun 27 '21 at 05:31
  • 1
    @ProgrammerHobbyist hey man I added the full code of the program, please check and help me to solve this. You can run it on your own machine for visual clarity, if you want. – Shivam Verma Jun 27 '21 at 05:43
  • Not sure if I understand what is this `rocket_clear`. You are drawing a rectangle for rocket and then another rectangle with x position - 1 for rocket clear? What behavior are you expecting? – kiner_shah Jun 27 '21 at 05:55
  • @kiner_shah yes exactly, so basically, I am using rocket() method to create new rectangle everytime and rocket_clear() method to clear the previous position of rectangle, to make a illusion of moving rocket forward. – Shivam Verma Jun 27 '21 at 07:50
  • 1
    your rocket function takes values for x and y. what you're passing in is values of "i" inside your loop for x, and "550" for y. so you're passing the y value as a constant. you need to calculate x and y first then pass them both in. – Jason Lang Jun 28 '21 at 16:01
  • @JasonLang thanks Jason for your valuable time and explanation :) – Shivam Verma Jun 30 '21 at 02:33

2 Answers2

2

Please read the comments starting with //=====

#include        <stdio.h>
#include        <conio.h>
#include     <graphics.h>
#include          <dos.h>
#include         <math.h>
#include       <stdlib.h>
#include     <iostream.h>

#define cld cleardevice()

//===== making these values as constants
static const int _moonRadius = 20, _earthRadius = 40, _marsRadius = 25;
static double projection_angle = 0.0;

void mars () {
    setfillstyle(9, BROWN);
    setcolor(BROWN);
    circle(getmaxx() - _marsRadius, 50, _marsRadius);
    floodfill(getmaxx() - 27, 52, BROWN);
}

void moon () {
    setfillstyle(9, WHITE);
    setcolor(WHITE);
    circle(getmaxx()/2, getmaxy()/2, _moonRadius);
    floodfill(getmaxx()/2, getmaxy()/2, WHITE);

    // Moon's gravitational area
    setfillstyle(SOLID_FILL, DARKGRAY);
    setcolor(DARKGRAY);
    circle(getmaxx()/2, getmaxy()/2, _moonRadius * 5);
}

void earth () {
    setfillstyle(9, GREEN);
    setcolor(GREEN);
    circle(40, getmaxy() - 100, _earthRadius);
    floodfill(42, getmaxy() - 102, GREEN);
}

void rocket (int x, int y) {
    setcolor(WHITE);
    //===== a box of size 10x10
    rectangle(x, y, x + 10, y - 10);
}

void rocket_clear (int x, int y) {
    setcolor(BLACK);
    //===== a box of size 10x10
    rectangle(x, y, x + 10, y - 10);
}

void main () {
    clrscr();
    int angle, speed;

    printf("Please provide input parameters.");
    printf("Enter projection angle (range from 5 to 90)\n");
    scanf("%d", &angle);
    //===== angle validation
    if (angle < 5 || angle > 90)
    {
        printf("Please provide angle in range [5, 90]\n");
        getch();
        return;
    }
    //===== calculate angle in radians
    projection_angle = (angle * 3.14) / 180.0;
    printf("projection_angle = %d\n", projection_angle);

    printf("Enter projection speed (range from 10 to 100)\n");
    scanf("%d", &speed);
    //===== speed validation
    if (speed < 10 || speed > 100)
    {
        printf("Please provide speed in range [10, 100]\n");
        getch();
        return;
    }

    int gd=DETECT, gm, i, j, k;
    initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");

    // Planets and rocket
    mars();
    moon();
    earth();
    rocket(80, 550); // let say initial pixel position x = 80, y = 550

    // Moving the rocket
    // Right now its only moving towards horizontal line, with speed implementation
    // Now here I want to implement the angle of projection

    //===== to store prev position
    int prev_i = 0, prev_j = 0;
    //===== increments will be constant for a given angle and speed
    const int x_inc = cos(projection_angle) * speed;
    const int y_inc = sin(projection_angle) * speed;

    //===== i and j will be updated with their respective increments
    for (i = 90, j = getmaxy() - 100; i < getmaxx() + 100 && j >= -10; i += x_inc, j -= y_inc) {
        // Also I am not sure about this loop's final range, should it go to getmaxx() or some other range

        //===== clear the previous position
        rocket_clear(prev_i, prev_j); // 550 is hard coded right now, so rocket will move only horizontally
        //===== draw rocket at current position
        rocket(i, j);
        //===== make current position as previous position
        prev_i = i;
        prev_j = j;
        //printf("x_inc = %lf, y_inc = %lf\n", cos(projection_angle) * speed, sin(projection_angle) * speed);
        delay(500 / speed);
    }
    getch();
}

Note: You can replace 3.14 with actual Pi. Refer this.

kiner_shah
  • 3,939
  • 7
  • 23
  • 37
0

Be sure that you are passing the angle in radians. To convert from degrees: radians=degrees*PI/180 (PI is defined in math.h which should be included by graphics.h) Make sure your variables are doubles.

Next you will probably want to bundle your X/Y coordinates in a struct so you can return the new position from a function:

typedef struct {
    double x;
    double y
} coord_t;

coord_t new_pos(double x, double y, double distance, double angle_deg) {
    coord_t result;
    double angle_rad = angle_deg * PI / 180;
    result.x = x + cos(angle_rad) * distance;
    result.y = y + sin(angle_rad) * distance;
    return result;
}

Or you could handle all the angles in radians so the function doesn't have to do the extra calculation.

gengumby
  • 29
  • 3