1
\$\begingroup\$

So the program below will move the mouse cursor in a circle all 360 degrees for 2,5 seconds (after 2,5 seconds, the program exits and the user can use his/her cursor normally).

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

const double RADIANS_PER_DEGREE = acos(-1.0) / 180.0; // acos(-1.0) = Pi
const int SLEEP_DURATION = 2500 / 360;

int APIENTRY wWinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPWSTR    lpCmdLine,
                      int       nCmdShow)
{
    const int screenWidth  = GetSystemMetrics(SM_CXSCREEN);
    const int screenHeight = GetSystemMetrics(SM_CYSCREEN);

    const int screenCenterX = screenWidth  / 2;
    const int screenCenterY = screenHeight / 2;

    const int radius = 3 * min(screenWidth / 2, screenHeight / 2) / 4;
    int currentDegree = 90;

    for (int degree = 0; degree < 360; degree++, currentDegree++) {
        const int x = screenCenterX + (int)(radius * cos(currentDegree * RADIANS_PER_DEGREE));
        const int y = screenCenterY - (int)(radius * sin(currentDegree * RADIANS_PER_DEGREE));

        SetCursorPos(x, y);
        Sleep(SLEEP_DURATION);
    }

    return 0;
}

Critique request

I would like to hear anything that comes to mind.

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Integer math for an integer problem

Consider a variation on Bresenham's circle algorithm for an integer only solution: faster and precise.

Note: Graphics processors use integer math for drawing circles on a screen, not floating point.

1 degree steps?

On high precision monitors, (think 2k * 2k or more) the result may look more circular (not a polygon) with finer steps. Above integer solution provides the best digitized circle.

Not standard C code

Good idea to use the systems best machine π, yet double global_variable = some_function(-1.0) is not valid. I suspect OP is not using a standard C compiler.

Alternative. Since π does not change, let the system derive the best machine π by providing code that the compiler will use even if double is many more than 64-bit.

// const double RADIANS_PER_DEGREE = acos(-1.0) / 180.0; // acos(-1.0) = Pi
const double RADIANS_PER_DEGREE = 3.1415926535897932384626433832795028841971  / 180.0;

Or define it

#ifdef M_PI // some implementation will define this, use if available.
  #define MY_PI M_PI
#else
  #define MY_PI 3.1415926535897932384626433832795028841971
#endif

const double RADIANS_PER_DEGREE = MY_PI / 180.0;

Pedantically, in rare cases, performing math like MY_PI / 180.0 will not result in the best RADIANS_PER_DEGREE and code could directly use

const double RADIANS_PER_DEGREE = 0.01745329251994329576923690768489;

Manually formatting?

Below hints that OP is not using an auto formatter. Code looks nice. Yet I would rather oblige a SW team to use auto formatting that spend time formatting.

int APIENTRY wWinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPWSTR    lpCmdLine,
                      int       nCmdShow)

Save time and increase productivity: auto-format.

Comment units

Naked code like const int SLEEP_DURATION = 2500 / 360; lacks units. How long is 2500? 2500 seconds, 2500 milliseconds? Do not lay the seeds for another big bucks units failure.

// const int SLEEP_DURATION = 2500 / 360;
const int SLEEP_DURATION = 2500 /* ms */ / 360;

Truncated quotient?

Note that 2500 / 360.0 is 6.9444... and 2500 / 360 is 6. Code may want to do things more precisely. At a minimum, consider a rounded quotient.

// const int SLEEP_DURATION = 2500 / 360;
const int SLEEP_DURATION = (2500 + 360/2) / 360;
\$\endgroup\$
1
\$\begingroup\$

continuing the item about the timer constant

const int SLEEP_DURATION = 2500 / 360;

I would do

const int RUN_TIME = 2500; // ms = 2.5 seconds
const int DEGREES_IN_CIRCLE; = 360
const int SLEEP_TIME = RUN_TIME / DEGREES_IN_CIRCLE;

and

for (int degree = 0; degree < DEGREES_IN_CIRLCE; degree++, currentDegree++)

never have magic numbers except maybe 0,1 and possibly 2 :-)

BTW +1 for const not #define

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.