Search code examples
cvisual-studiodrawmath.hgdi

How to draw circle with sin and cos in C?


I have a problem about make some circle orbit (solar system stimulation) in C.

Actually, I did it about a day. but I can't figure it out.

First, how to change the planets movement speed? Some friends told me that I can use "If" for speed arrange, but I failed....

Second, Location setting. I draw some circle with ellipse but I don't know how to make orbit. my earth orbit goes wrong... there are some codes that I made.

#include <Windows.h>
#include <stdio.h>
#include <math.h>

#define solar_size 30
#define earth_size 16
#define PI 3.141592654
#define MOVE_SPEED 3
#define rad angle*180/PI

int angle;
double sun_x,sun_y,earth_x,earth_y;
double x,y;
int dx;
int dy;
int i;

int main(void) {

    HWND hwnd = GetForegroundWindow();
    HDC hdc = GetWindowDC(hwnd);

    SelectObject(hdc, CreateSolidBrush(RGB(0, 0, 0)));
    Rectangle(hdc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));

    TextOut(hdc, 250, 450, L"solar system Simulation", 23); 

    while (1) {

        sun_x = 250;
        sun_y = 250;

        earth_x = sun_x + 40;
        earth_y = sun_y + 40;

        SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(255, 0, 0)));
        SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
        Ellipse(hdc, sun_x, sun_y, sun_x + solar_size, sun_y + solar_size);

        for (angle = 0; angle <= 360; angle++) {

            SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 0, 220)));
            SelectObject(hdc, CreateSolidBrush(RGB(0, 0, 220)));
            Ellipse(hdc, earth_x, earth_y, earth_x + earth_size, earth_y + earth_size);

            Sleep(50);

            SelectObject(hdc, CreatePen(PS_SOLID, 3, RGB(0, 0, 0)));
            SelectObject(hdc, CreateSolidBrush(RGB(0, 0, 0)));
            Ellipse(hdc, earth_x + 30, earth_y + 30, earth_x + earth_size, earth_y  + earth_size);

            earth_x = 40 * cos(rad)+40;
            earth_y = 40 * sin(rad)+40;

                    }
        continue;
    }
}

enter image description here


Solution

  • Your code suffers from being unorganized. For example, you mix the variables like earth_size and hard-wired numbers like 16 freely. That's a recipe for disaster. Please try to be more systematic.

    It's hard not to make an answer a laundry list of errors.

    The position (px, py) on a circle with centre (cx, cy) and radius r is:

    px = cx + r * cos(angle)
    py = cy + r * sin(angle)
    

    Therefore, your initialization is wrong:

    earth_x = sun_x + 40;
    earth_y = sun_y + 40;      // should be just sun_y
    

    The way the Ellipse function in GDI works, your drawing command should look like:

    Ellipse(hdc, earth_x - earth_size / 2, earth_y - earth_size / 2,
                 earth_x + earth_size / 2, earth_y + earth_size / 2);
    

    Perhaps it is useful to collect the data of the celestial bodies (position, size, colour) in a struct and write a drawing function for it that just says DrawBody(hdc, earth), so that you don't have to repeat (viz copy and paste) the drawing code.

    As for your speed: One possible source of error is here:

    #define rad angle*180/PI
    

    That's the wrong way round.

    Finally, learn how SelectObject works: You should save the return value in a variable and select it back to the DC after you are done. If you don't do that, you will leak GDI objects. You can see how many GDI objects your application uses in the Task Manager. If that number grows constantly, you are leaking objects. Eventually, your application will behave strangely.