C Graphics - How to move an object with specific angle
Asked Answered
C

2

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 :)

Contagion answered 27/6, 2021 at 4:5 Comment(19)
Are you giving the angle values as arguments to the sin and cos functions in radians?Gerhart
Is it WinBGI graphics? Can you provide the full code so that the readers can proceed with further debugging?Lecialecithin
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 ......Esra
@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 cosContagion
@ProgrammerHobbyist this is not winBGI graphics, this is TurboC++ graphics using graphics.h libraryContagion
@PsychopathicAzula So you are saying the above code should run inside a loop where in each iteration distance will increase based on speed.Contagion
@ShivamVerma yesEsra
I know. The graphics.h contains WinBGI graphics implementation.Lecialecithin
Can you edit the question and add the code? I mean, full code.Lecialecithin
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.Naples
@AdrianMole I am passing the angle directly to the sin cos, I mean I am not converting it into Radians.Contagion
@Scott do you have any idea man, what will be the equation look like for rocket launching scenario?Contagion
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, and ask a specific question related to that code, and we'll try to help.Nutmeg
Much more complicated. Search for “orbital mechanics”, or something like that.Naples
@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.Contagion
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?Amora
@Amora 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.Contagion
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.Azole
@JasonLang thanks Jason for your valuable time and explanation :)Contagion
A
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.

Amora answered 27/6, 2021 at 9:45 Comment(0)
G
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.

Goldeye answered 27/6, 2021 at 6:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.