我刚刚开始学习C++。我要做的就是画一条线到指定的坐标,该坐标作为方法的输入。我使用MoveToEx设置每个循环的起点(在具有不同参数的循环中调用此函数),并提供要绘制车道的坐标。

任何想法如何使其循环工作?

我的代码类似于:

void Clock::drawSecondLine(float x,float y) {
    HWND console_handle = GetConsoleWindow();
    HDC device_context = GetDC(console_handle);
    HPEN pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
    SelectObject(device_context, pen);

    MoveToEx(device_context, 0, 0, NULL);
    Ellipse(device_context, 400, 0, 0, 400);
    MoveToEx(device_context, 200, 200, NULL);
    LineTo(device_context, (int)x, (int)y);

    ReleaseDC(console_handle, device_context);
    cin.ignore();
}

和循环:
void Zegar::startClock() {
    while (true) {
        drawSecondLine(laneShowingSecond.getX(), laneShowingSecond.getY());
        laneShowingSecond.movePointByRadius(RADIUS_PER_SECOND);
        Sleep(1000);
        increaseSecond();
    }
}

最佳答案

这是一些示例代码(我正在VStudio 2k10中运行)。

注释:

  • 尽管它被编译为C++(并使用了iostream等一些C++功能-意味着它不会被编译为C),但它仍然是普通的旧C。
  • 它有很多丑陋的东西和NO-NO(例如全局变量,很多定义,C和C++代码的混合,在控制台窗口上绘制等等)。目的是要建立一个PoC。该代码可以在以后清除。
  • 从边界矩形(RECT_*定义了(400,0,0,400)),我正在使用一些简单的数学计算来提取中心坐标以及X和Y轴上的半径(由于该矩形是一个平方,两个半径相等,因此我们遇到了特殊情况,其中椭圆实际上是一个圆)。
  • nextPoint函数是代码中laneShowingSecond.getX(), laneShowingSecond.getY()的替换。
  • 将所有只需要执行一次(在开始时)的内容放入init函数中。请注意,如果在初始化过程中出现问题,则会退出并显示错误代码(
  • 类似地,最后要执行的任何清理工作都放在cleanup函数中(这里我不必费心检查返回代码,因为它无论如何都退出了)。
  • draw函数包含绘图循环。在每次迭代中:
  • Angular 增加INCERMENT_DEG(默认为30°)。
  • 使用一些简单的三角公式计算椭圆上的下一个点。
  • 完成绘制。
  • 等待ITERATION_SLEEP_TIME毫秒(我将其设置为200,以避免为绘制的每一行等待一秒钟)。
  • 注意:
  • 到达360°或2 * PI Radians(全天候)后停止,因为一遍又一遍地绘制相同的线没有意义。
  • 绘制是逆时针执行的(三角学中的正角); xOy的原点(O(0,0))也是屏幕的左上角。
  • 通过为它们分配各种值来查看我用注释标记的定义,并查看图形如何变化。

  • main.cpp:
    #include <iostream>
    #define _USE_MATH_DEFINES
    #include <math.h>
    #include <Windows.h>
    
    #define RECT_LEFT 400  // Modify any of these 4 RECT_* values to get different ellipse shapes.
    #define RECT_TOP 0
    #define RECT_RIGHT 0
    #define RECT_BOT 400
    
    #define ITERATION_SLEEP_TIME 200  // Sleep time while in loop.
    
    #define INCERMENT_DEG 30  // 30 degrees per step; a full circle has 360 (2 * PI  RAD).
    #define M_PI_180 M_PI / 180
    
    using std::cout;
    using std::endl;
    
    typedef enum {DRAW_RADII, DRAW_POLY} DrawMethod;
    
    const int radiusX = abs(RECT_RIGHT - RECT_LEFT) / 2;
    const int radiusY = abs(RECT_BOT - RECT_TOP) / 2;
    const int centerX = (RECT_RIGHT + RECT_LEFT) / 2;
    const int centerY = (RECT_BOT + RECT_TOP) / 2;
    
    HWND hwnd = NULL;
    HDC hdc = NULL;
    HPEN hpen = NULL;
    
    DrawMethod meth = DRAW_RADII;  // Modify this to DRAW_POLY to draw a polygon instead of the "bike wheel".
    
    int deg = 0;
    double x = 0, y = 0;
    
    
    void nextPoint(int degree, double *x, double *y) {
        *x = centerX + radiusX * cos(M_PI_180 * degree );
        *y = centerY - radiusY * sin(M_PI_180 * degree);
    }
    
    int init() {
        if ((hwnd = GetConsoleWindow()) == NULL) {
            cout << "GetConsoleWindow error: " << GetLastError() << endl;
            return -1;
        }
        if ((hdc = GetDC(hwnd)) == NULL) {
            cout << "GetDC error: " << GetLastError() << endl;
            return -2;
        }
        if ((hpen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0))) == NULL) {
            cout << "CreatePen error: " << GetLastError() << endl;
            return -3;
        }
        SelectObject(hdc, hpen);
        Ellipse(hdc, RECT_LEFT, RECT_TOP, RECT_RIGHT, RECT_BOT);
        nextPoint(deg, &x, &y);
        if (meth == DRAW_RADII) {
            MoveToEx(hdc, centerX, centerY, NULL);
            LineTo(hdc, (int)x, (int)y);
        } else if (meth == DRAW_POLY) {
            MoveToEx(hdc, (int)x, (int)y, NULL);
        }
        return 0;
    }
    
    void draw() {
        while (deg < 360) {
            deg += INCERMENT_DEG;
            nextPoint(deg, &x, &y);
            if (meth == DRAW_RADII) {
                MoveToEx(hdc, centerX, centerY, NULL);
                LineTo(hdc, (int)x, (int)y);
            } else if (meth == DRAW_POLY) {
                LineTo(hdc, (int)x, (int)y);
            } else
                break;
            Sleep(ITERATION_SLEEP_TIME);
        }
    }
    
    void cleanup() {
        if (hpen) {
            DeleteObject(hpen);
        }
        if (hwnd && hdc) {
            ReleaseDC(hwnd, hdc);
        }
    }
    
    int main() {
        if (!init())
            draw();
        cleanup();
        return 0;
    }
    

    关于c++ - WinApi Line不刷新线,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42517628/

    10-11 23:05
    查看更多