powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
22 сообщений из 22, страница 1 из 1
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40043485
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите в чем ошибка?

1. У меня не поворачивается эллипс см. в коде строки 248-251, 305-317, 326-339, 403-414, 480-490.

2. И у меня не отображается надпись - строки 302,303 - аналогичная проблема с поворотом в ключевых кадрах.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
#include <windows.h>
#include <windowsX.h>
#include <tchar.h>
#include <gdiplus.h>
#include <vector>
#include <gdiplusgraphics.h>    
#include <gdiplusheaders.h>
#include "Math.h"
#define ID_TIMER    1
#pragma comment(lib,"Gdiplus.lib")


using namespace Gdiplus;
using namespace std;

Bitmap* imgTextureMetall;
HWND hWnd = NULL;
MSG  msg;
BOOL bRet;
ULONG_PTR           gdiToken;
GdiplusStartupInput gdiStartupInput;
HDC  hdc;
PAINTSTRUCT ps;
//Bitmap* imgTrain = NULL;

/* -- ANIMATION DATA --*/
// массив точек, характеризующие ключевые и промежуточные кадры
std::vector<Gdiplus::PointF> startKeyVector;
Gdiplus::PointF* A;
Gdiplus::PointF* B;
Gdiplus::PointF* P;
Bitmap* imgRoad;
Image* gifTrain;
UINT framesCount;
UINT indexCurrentFrame;
int stage = 0;              // переменная для интерполяции
float t = 0.f;              // параметр для интерполяции
float k_sizeX = 0.6;            // коэффициент масштабирования
float k_sizeY = 0.6;            // коэффициент масштабирования
PointF sizeWheel(70, 70);

/* ----------------------------------------------------- */
LRESULT CALLBACK MyWindowsProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void OnDestroy(HWND hwnd);
void OnDisplay(HDC hdc);

void CopyArrToVector(PointF _array[], std::vector<Gdiplus::PointF>& _vector, int _size);
void CopyPointFToVector(PointF _point, std::vector<Gdiplus::PointF>& _vector);
PointF Tween(const PointF& A, const PointF& B, float t);
void RotateTransform(REAL angle, MatrixOrder order);
void Tween(const PointF* A, const PointF* B, PointF* P, int count, float t);
void IncrementT(int framesCount);
void OnDisplay_Wheels(Graphics& drawingBoard, PointF centerPointWheel, PointF sizeWheel, int wheels, float gap, SolidBrush& Brush1, Pen& Pen1, SolidBrush& Brush2, Pen& Pen2, std::vector<Gdiplus::PointF>& Vector);

/* ----------------------------------------------------- */
int WINAPI _tWinMain(HINSTANCE hInctance, HINSTANCE, LPTSTR lpszCmdLine, int nCmdShow) {
    WNDCLASSEX wndcls = { sizeof(WNDCLASSEX) };
    wndcls.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wndcls.lpfnWndProc = MyWindowsProc;
    wndcls.hInstance = hInctance;
    wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndcls.hbrBackground = NULL; // (HBRUSH)GetStockObject(WHITE_BRUSH); // извлекает дескриптор предопределенного пера из wingdi.h
    wndcls.lpszMenuName = NULL;
    wndcls.lpszClassName = TEXT("MainWindow");
    wndcls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (0 == RegisterClassEx(&wndcls)) {
        return -1;
    }

    Status stRet = GdiplusStartup(&gdiToken, &gdiStartupInput, NULL);
    imgRoad = new Bitmap(L"road.jpg");

    hWnd = CreateWindowEx(0, TEXT("MainWindow"), TEXT("KGG3_animation"), WS_OVERLAPPEDWINDOW, 50, 50, 1400, 800, NULL, NULL, hInctance, NULL);
    if (hWnd == NULL) {
        return -1;
    }
    ShowWindow(hWnd, nCmdShow);
    //imgTrain = new Bitmap(L"my_train.jpg");
    imgTextureMetall = new Bitmap(L"texture.jpeg");
    //UpdateWindow(hWnd);

    if (Ok == stRet) {
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (bRet == -1) {
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    GdiplusShutdown(gdiToken);
    return (int)msg.wParam;
}

/* ----------------------------------------------------- */
LRESULT CALLBACK MyWindowsProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {

    case WM_ERASEBKGND: // подавить мерцание
        return 1;

    case WM_CREATE:
        gifTrain = Image::FromFile(L"Lunohod.gif");
        indexCurrentFrame = 0;
        if (NULL != gifTrain) {
            framesCount = gifTrain->GetFrameCount(&FrameDimensionTime);
        }
        SetTimer(hWnd, ID_TIMER, 50, NULL);  // 3-ий параметр - частота изменения кадров 40мс; 4-ый - функция обратного вызова. 
        return 0; //Если NULL, то посылается сообщение WM_TIMER

    case WM_TIMER:
        indexCurrentFrame = (indexCurrentFrame + 1) % framesCount;
        IncrementT(framesCount);
        gifTrain->SelectActiveFrame(&FrameDimensionTime, indexCurrentFrame);
        InvalidateRect(hWnd, NULL, FALSE);
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps); // получили дескриптор устройства по hWnd
        OnDisplay(hdc);
        EndPaint(hWnd, &ps);
        return 0;

        HANDLE_hWnd, WM_DESTROY, OnDestroy;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
void IncrementT(int framesCount) {
    if (t < 0) {
        stage = 0;
        t = 0;
    }
    else {
        t += (float)1 / framesCount * 3;
        if (t > 1) {
            t = 0;
            stage += 1;
        }
    }
}
void OnDestroy(HWND hwnd) {
    PostQuitMessage(0);
}
void CopyArrToVector(PointF _array[], std::vector<Gdiplus::PointF>& _vector, int _size) {
    for (int i = 0; i < _size; i++) {
        _vector.push_back(_array[i]);
    }
}
void CopyPointFToVector(PointF _point, std::vector<Gdiplus::PointF>& _vector) {
    _vector.push_back(_point);
}
PointF Tween(const PointF& A, const PointF& B, float t) {
    return PointF(A.X * (1.f - t) + B.X * t, A.Y * (1.f - t) + B.Y * t);
}
void Tween(const PointF* A, const PointF* B, PointF* P, int count, float t) {
    for (int i = 0; i < count; ++i) {
        P[i] = Tween(A[i], B[i], t);
    }
}
void OnDisplay_Wheels(Graphics& drawingBoard, PointF centerPointWheel, PointF sizeWheel, int wheels, float gap, SolidBrush& Brush1, Pen& Pen1, SolidBrush& Brush2, Pen& Pen2, std::vector<Gdiplus::PointF>& Vector) {

}

void RotateTransform(float angle)
{
}

void RotateTransformAngle(float angle)
{
}

void RotateTransform(float angle, MatrixOrder order)
{
}

void OnDisplay(HDC hdc) {
    Graphics g(hdc);
    Rect rectInstance;
    g.GetVisibleClipBounds(&rectInstance);
    Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g);
    Graphics drawingBoard(&backBuffer);
    drawingBoard.Clear(Color::White);
    drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);
    Matrix affinMatrix;

    /*-- общие атрибуты --*/
    SolidBrush greenBrush(Color(0, 180, 0));
    SolidBrush yellowBrush(Color::Yellow);
    SolidBrush orangeBrush(Color::Orange);
    SolidBrush redBrush(Color(255, 50, 50));
    SolidBrush blackBrush(Color(20, 20, 20));
    HatchBrush hatchBrush(HatchStyleDarkVertical, Color::Silver, Color::Wheat);
    TextureBrush textureBrush(imgTextureMetall);
    Pen greenPen(Color(0, 150, 0));
    Pen redPen(Color(255, 0, 0));
    Pen blackPen(Color(0, 0, 0));
    Pen orangePen(Color::Orange);
    Pen yellowPen(Color::Yellow);
    Pen WhitePen(Color(255, 255, 255));
    Pen texturePen(&textureBrush, 15);
    Color colorWhite(Color::White);
    SolidBrush WhiteBrush(Color::White);
    SolidBrush DarkGrayBrush(Color(108, 108, 108));
    SolidBrush BlueBrush(Color(56, 44, 144));
    SolidBrush SaddleBrownBrush(Color(128, 68, 4));
    SolidBrush BrunBrown(Color(68, 36, 4));
    SolidBrush DarkTurquoiseBrown(Color(0, 206, 209));
    SolidBrush DarkCyanBrown(Color(0, 139, 139));
    Pen BrushPen(Color(68, 36, 4));
    Pen BluePen(Color(56, 44, 144));
    Color windowsColors[4] = {
        Color::MediumTurquoise,
        Color::SkyBlue,
        Color::MediumTurquoise,
        Color::SteelBlue,
    };
    int n = 4;
    int wheels = 4; // кол-во колес

    //линейный градиент
    LinearGradientBrush pthGrBrush(Rect(200, 200, 300, 150), Color::White, Color::White, 45.f);
    LinearGradientBrush pthGrBrush2(Rect(200, 200, 300, 150), Color::White, Color::White, 45.f);
    Color colors[3] = { Color(255, 0, 255, 255), Color(255, 0, 155, 155), Color(255, 0, 0, 0) };
    float pos[3] = { 0.0f, 0.3f, 1.0f };
    Color colors1[3] = { Color(255, 0, 255, 255), Color(255, 0, 155, 155), Color(255, 0, 0, 0) };
    float pos1[3] = { 0.0f, 0.3f, 1.0f };

    //составное перо
    Pen CompPen(Color::Black, 6.f);
    float comp[6] = { 0.0f, 0.2f, 0.3f, 0.7f, 0.8f, 1.0f };
    CompPen.SetCompoundArray(comp, 6);
    WrapMode wrapMode = WrapModeTile;

    // дорога
    drawingBoard.DrawLine(&texturePen, 0, 488, 1400, 488);
    RectF rectim(100.f, 520.f, 400.f, 200.f);
    drawingBoard.DrawImage(gifTrain, rectim);

    /* ---------------- ПЕРВЫЙ КЛЮЧЕВОЙ КАДР ---------------- */
    if (stage == 0 && t == 0) {
        /*-- левая половина рисунка --*/

        // Большой Эллипс
        Matrix* m;
        PointF pointsc(120, 90);
        CopyPointFToVector(pointsc, startKeyVector);
        affinMatrix.RotateAt(1, PointF(pointsc.X, pointsc.Y));

        //голубой корпус
        PointF points[4] = { PointF(190, 410), PointF(150, 310), PointF(450, 310), PointF(400, 410) };
        // +4
        CopyArrToVector(points, startKeyVector, 4);
        drawingBoard.FillPolygon(&DarkTurquoiseBrown, points, 4);
        drawingBoard.DrawPolygon(&blackPen, points, 4);

        //оконтовочный бортик (голубой)
        PointF pointsa[4] = { PointF(120, 300), PointF(480, 300), PointF(480, 320), PointF(120, 320) };
        // +4
        CopyArrToVector(pointsa, startKeyVector, 4);
        drawingBoard.FillPolygon(&DarkCyanBrown, pointsa, 4);
        drawingBoard.DrawPolygon(&blackPen, pointsa, 4);

        //серая антенна
        PointF pointsb[4] = { PointF(350, 300), PointF(510, 140), PointF(513, 143), PointF(355, 300) };
        // +4
        CopyArrToVector(pointsb, startKeyVector, 4);
        drawingBoard.FillPolygon(&DarkGrayBrush, pointsb, 4);
        drawingBoard.DrawPolygon(&blackPen, pointsb, 4);
        drawingBoard.DrawCurve(&CompPen, pointsb, 4);

        //линейный градиент 1
        PointF windowsPoints[5] = { PointF(190, 410), PointF(150, 310), PointF(295, 410), PointF(450, 310), PointF(400, 410) };
        CopyArrToVector(windowsPoints, startKeyVector, 5);
        // +4
        PointF centerPointWindow(295, 410);  // координаты центра для окна
        // +1
        PathGradientBrush pthGrBrush(windowsPoints, 5); // кисть градиента контура
        pthGrBrush.SetCenterPoint(centerPointWindow);
        pthGrBrush.SetInterpolationColors(colors, pos, 5);
        pthGrBrush.SetSurroundColors(windowsColors, &n);
        drawingBoard.FillPolygon(&pthGrBrush, windowsPoints, 5);
        drawingBoard.DrawPolygon(&blackPen, windowsPoints, 5);

        // колеса
        float gap = 75.f; // расстояние между колесами
        PointF centerPointWheel1(190, 440);  // центр колеса
        PointF centerPointWheel2(263, 440);  // центр колеса
        PointF centerPointWheel3(337, 440);  // центр колеса
        PointF centerPointWheel4(410, 440);  // центр колеса
        CopyPointFToVector(centerPointWheel1, startKeyVector);
        CopyPointFToVector(centerPointWheel2, startKeyVector);
        CopyPointFToVector(centerPointWheel3, startKeyVector);
        CopyPointFToVector(centerPointWheel4, startKeyVector);



        // Надпись
        Font font(L"Courier", 25.f, FontStyleBold);
        drawingBoard.DrawString(L"СССР", -1, &font, PointF(250, 330), &SaddleBrownBrush);

        P = new Gdiplus::PointF[startKeyVector.size()];
        A = new Gdiplus::PointF[startKeyVector.size()];
        B = new Gdiplus::PointF[startKeyVector.size()];
        for (int i = 0; i < startKeyVector.size(); ++i) {
            A[i] = startKeyVector[i];
            B[i] = startKeyVector[i];
        }

        affinMatrix.Translate(300.f, -100.f);
        affinMatrix.Scale(k_sizeX, k_sizeY);
        affinMatrix.TransformPoints(B, startKeyVector.size());
        affinMatrix.TransformPoints(P, startKeyVector.size());
        g.RotateTransform(90);
        g.DrawImage(&backBuffer, rectInstance);
    }
    else
        //----------------------------------------------------------------------------- stage == 0 && t <= 1.f
        if (stage == 0 && t <= 1) {
            Tween(A, B, P, startKeyVector.size(), t);
            int _i = 0;

            //Большой Эллипс
            Matrix m;
            PointF pointsc = { PointF(P[_i].X, P[_i].Y) };
            for (int i = 0; i < wheels; i++) {
                float kx = 1 - ((1 - k_sizeX) * t);
                float ky = 1 - ((1 - k_sizeY) * t);
                g.RotateTransform(90);
                drawingBoard.FillEllipse(&SaddleBrownBrush, float(pointsc.X - sizeWheel.X * kx), float(pointsc.Y - sizeWheel.Y * ky), sizeWheel.X * kx * 2, sizeWheel.Y * ky * 4);
                drawingBoard.DrawEllipse(&BrushPen, float(pointsc.X - sizeWheel.X * kx), float(pointsc.Y - sizeWheel.Y * ky), sizeWheel.X * kx * 2, sizeWheel.Y * ky * 4);
                //affinMatrix.RotateAt(0.52, PointF(pointsc[i].X, pointsc[i].Y));
                //drawingBoard.FillPolygon(&SaddleBrownBrush, pointsc, 1);
                //drawingBoard.DrawPolygon(&redPen, pointsc, 1);
            }
            _i += 1;

            //голубой корпус
            PointF points[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            drawingBoard.FillPolygon(&DarkTurquoiseBrown, points, 4);
            drawingBoard.DrawPolygon(&blackPen, points, 4);
            _i += 4;

            //оконтовочный бортик (голубой)
            PointF pointsa[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            _i += 4;
            drawingBoard.FillPolygon(&DarkCyanBrown, pointsa, 4);
            drawingBoard.DrawPolygon(&blackPen, pointsa, 4);

            //серая антенна
            PointF pointsb[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            _i += 4;
            drawingBoard.FillPolygon(&DarkGrayBrush, pointsb, 4);
            drawingBoard.DrawPolygon(&blackPen, pointsb, 4);
            drawingBoard.DrawCurve(&CompPen, pointsb, 4);

            //линейный градиент 1
            PointF windowsPoints[5] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y), PointF(P[_i + 4].X, P[_i + 4].Y) };
            _i += 4;
            PointF centerPointWindow(P[_i].X, P[_i].Y); // координаты центра для окна
            _i += 1;
            PathGradientBrush pthGrBrush(windowsPoints, 5); // кисть градиента контура
            pthGrBrush.SetCenterPoint(centerPointWindow);
            pthGrBrush.SetInterpolationColors(colors, pos, 5);
            pthGrBrush.SetSurroundColors(windowsColors, &n);
            drawingBoard.FillPolygon(&pthGrBrush, windowsPoints, 5);
            drawingBoard.DrawPolygon(&blackPen, windowsPoints, 5);

            // колеса
            PointF centerPointWheel1[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            for (int i = 0; i < wheels; i++) {
                float kx = 1 - ((1 - k_sizeX) * t);
                float ky = 1 - ((1 - k_sizeY) * t);
                Rect rectWheel(centerPointWheel1[i].X - sizeWheel.X * kx / 2, centerPointWheel1[i].Y - sizeWheel.Y * ky / 2, sizeWheel.X * kx, sizeWheel.Y * ky);
                drawingBoard.FillEllipse(&SaddleBrownBrush, rectWheel);
                drawingBoard.DrawEllipse(&BrushPen, rectWheel);
                drawingBoard.FillEllipse(&WhiteBrush, float(centerPointWheel1[i].X - sizeWheel.X * kx / 3), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 3), sizeWheel.X * kx * 0.65, sizeWheel.Y * ky * 0.65);
                drawingBoard.DrawEllipse(&BrushPen, float(centerPointWheel1[i].X - sizeWheel.X * kx / 3), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 3), sizeWheel.X * kx * 0.65, sizeWheel.Y * ky * 0.65);
                drawingBoard.FillEllipse(&SaddleBrownBrush, float(centerPointWheel1[i].X - sizeWheel.X * kx / 5), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 5), sizeWheel.X * kx * 0.4, sizeWheel.Y * ky * 0.4);
                drawingBoard.DrawEllipse(&BrushPen, float(centerPointWheel1[i].X - sizeWheel.X * kx / 5), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 5), sizeWheel.X * kx * 0.4, sizeWheel.Y * ky * 0.4);
            }
            _i += 4;

            g.DrawImage(&backBuffer, rectInstance);
        }
    /* ---------------- ВТОРОЙ КЛЮЧЕВОЙ КАДР ---------------- */
    //----------------------------------------------------------------------------- stage == 1 && t <= 1.f
        else if (stage == 1 && 0 <= t <= 1) {
            int _i = 0;
            if (t == 0) {
                for (int i = 0; i < startKeyVector.size(); ++i) {
                    A[i] = B[i];
                }
                affinMatrix.Translate(300.f, 300.f);
                affinMatrix.TransformPoints(B, startKeyVector.size());
            }
            Tween(A, B, P, startKeyVector.size(), t);

            //Большой Эллипс
            Matrix m;
            PointF pointsc = { PointF(P[_i].X, P[_i].Y) };
            for (int i = 0; i < wheels; i++) {
                float kx = k_sizeX;
                float ky = k_sizeY;
                g.RotateTransform(90);
                drawingBoard.FillEllipse(&SaddleBrownBrush, float(pointsc.X - sizeWheel.X * kx), float(pointsc.Y - sizeWheel.Y * ky), sizeWheel.X * kx * 2, sizeWheel.Y * ky * 4);
                drawingBoard.DrawEllipse(&BrushPen, float(pointsc.X - sizeWheel.X * kx), float(pointsc.Y - sizeWheel.Y * ky), sizeWheel.X * kx * 2, sizeWheel.Y * ky * 4);
                //drawingBoard.FillPolygon(&DarkCyanBrown, pointsc, 1);
                //drawingBoard.DrawPolygon(&redPen, pointsc, 1);
            }
            _i += 1;

            //голубой корпус
            PointF points[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            drawingBoard.FillPolygon(&DarkTurquoiseBrown, points, 4);
            drawingBoard.DrawPolygon(&blackPen, points, 4);
            _i += 4;

            //оконтовочный бортик (голубой)
            PointF pointsa[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            _i += 4;
            drawingBoard.FillPolygon(&DarkCyanBrown, pointsa, 4);
            drawingBoard.DrawPolygon(&blackPen, pointsa, 4);

            //серая антенна
            PointF pointsb[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            _i += 4;
            drawingBoard.FillPolygon(&DarkGrayBrush, pointsb, 4);
            drawingBoard.DrawPolygon(&blackPen, pointsb, 4);
            drawingBoard.DrawCurve(&CompPen, pointsb, 4);

            //линейный градиент 1
            PointF windowsPoints[5] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y), PointF(P[_i + 4].X, P[_i + 4].Y) };
            _i += 4;
            PointF centerPointWindow(P[_i].X, P[_i].Y); // координаты центра для окна
            _i += 1;
            PathGradientBrush pthGrBrush(windowsPoints, 5); // кисть градиента контура
            pthGrBrush.SetCenterPoint(centerPointWindow);
            pthGrBrush.SetInterpolationColors(colors, pos, 5);
            pthGrBrush.SetSurroundColors(windowsColors, &n);
            drawingBoard.FillPolygon(&pthGrBrush, windowsPoints, 5);
            drawingBoard.DrawPolygon(&blackPen, windowsPoints, 5);

            // колеса
            PointF centerPointWheel1[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            for (int i = 0; i < wheels; i++) {
                float kx = k_sizeX;
                float ky = k_sizeY;
                Rect rectWheel(centerPointWheel1[i].X - sizeWheel.X * kx / 2, centerPointWheel1[i].Y - sizeWheel.Y * ky / 2, sizeWheel.X * kx, sizeWheel.Y * ky);
                drawingBoard.FillEllipse(&SaddleBrownBrush, rectWheel);
                drawingBoard.DrawEllipse(&BrushPen, rectWheel);
                drawingBoard.FillEllipse(&WhiteBrush, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.65), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.65), sizeWheel.X * kx * 0.65, sizeWheel.Y * ky * 0.65);
                drawingBoard.DrawEllipse(&BrushPen, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.65), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.65), sizeWheel.X * kx * 0.65, sizeWheel.Y * ky * 0.65);
                drawingBoard.FillEllipse(&SaddleBrownBrush, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.4), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.4), sizeWheel.X * kx * 0.4, sizeWheel.Y * ky * 0.4);
                drawingBoard.DrawEllipse(&BrushPen, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.4), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.4), sizeWheel.X * kx * 0.4, sizeWheel.Y * ky * 0.4);
            }
            _i += 4;
            g.DrawImage(&backBuffer, rectInstance);
        }

    /* ---------------- ТРЕТИЙ КЛЮЧЕВОЙ КАДР ---------------- */
    //----------------------------------------------------------------------------- stage == 2 && t <= 1.f
        else if (stage == 2 && 0 <= t <= 1) {
            int _i = 0;
            if (t == 0) {
                for (int i = 0; i < startKeyVector.size(); ++i) {
                    A[i] = B[i];
                }
                affinMatrix.Translate(250, 0);
                affinMatrix.RotateAt(90, PointF(850.f, 250.f));
                //affinMatrix.RotateTransform(90);
                affinMatrix.TransformPoints(B, startKeyVector.size());
            }
            Tween(A, B, P, startKeyVector.size(), t);

            //Большой Эллипс
            Matrix m;
            PointF pointsc = { PointF(P[_i].X, P[_i].Y) };
            for (int i = 0; i < wheels; i++) {
                float kx = k_sizeX;
                float ky = k_sizeY;
                drawingBoard.FillEllipse(&SaddleBrownBrush, float(pointsc.X - sizeWheel.X * kx), float(pointsc.Y - sizeWheel.Y * ky), sizeWheel.X * kx * 2, sizeWheel.Y * ky * 4);
                drawingBoard.DrawEllipse(&BrushPen, float(pointsc.X - sizeWheel.X * kx), float(pointsc.Y - sizeWheel.Y * ky), sizeWheel.X * kx * 2, sizeWheel.Y * ky * 4);
                //drawingBoard.FillPolygon(&DarkCyanBrown, pointsc, 1);
                //drawingBoard.DrawPolygon(&redPen, pointsc, 1);
            }
            _i += 1;

            //голубой корпус
            PointF points[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            drawingBoard.FillPolygon(&DarkTurquoiseBrown, points, 4);
            drawingBoard.DrawPolygon(&blackPen, points, 4);
            _i += 4;

            //оконтовочный бортик (голубой)
            PointF pointsa[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            _i += 4;
            drawingBoard.FillPolygon(&DarkCyanBrown, pointsa, 4);
            drawingBoard.DrawPolygon(&blackPen, pointsa, 4);

            //серая антенна
            PointF pointsb[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            _i += 4;
            drawingBoard.FillPolygon(&DarkGrayBrush, pointsb, 4);
            drawingBoard.DrawPolygon(&blackPen, pointsb, 4);
            drawingBoard.DrawCurve(&CompPen, pointsb, 4);

            //линейный градиент 1
            PointF windowsPoints[5] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y), PointF(P[_i + 4].X, P[_i + 4].Y) };
            _i += 4;
            PointF centerPointWindow(P[_i].X, P[_i].Y); // координаты центра для окна
            _i += 1;
            PathGradientBrush pthGrBrush(windowsPoints, 5); // кисть градиента контура
            pthGrBrush.SetCenterPoint(centerPointWindow);
            pthGrBrush.SetInterpolationColors(colors, pos, 5);
            pthGrBrush.SetSurroundColors(windowsColors, &n);
            drawingBoard.FillPolygon(&pthGrBrush, windowsPoints, 5);
            drawingBoard.DrawPolygon(&blackPen, windowsPoints, 5);

            // колеса
            PointF centerPointWheel1[4] = { PointF(P[_i].X, P[_i].Y), PointF(P[_i + 1].X, P[_i + 1].Y), PointF(P[_i + 2].X, P[_i + 2].Y), PointF(P[_i + 3].X, P[_i + 3].Y) };
            for (int i = 0; i < wheels; i++) {
                float kx = k_sizeX;
                float ky = k_sizeY;
                Rect rectWheel(centerPointWheel1[i].X - sizeWheel.X * kx / 2, centerPointWheel1[i].Y - sizeWheel.Y * ky / 2, sizeWheel.X * kx, sizeWheel.Y * ky);
                drawingBoard.FillEllipse(&SaddleBrownBrush, rectWheel);
                drawingBoard.DrawEllipse(&BrushPen, rectWheel);
                drawingBoard.FillEllipse(&WhiteBrush, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.65), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.65), sizeWheel.X * kx * 0.65, sizeWheel.Y * ky * 0.65);
                drawingBoard.DrawEllipse(&BrushPen, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.65), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.65), sizeWheel.X * kx * 0.65, sizeWheel.Y * ky * 0.65);
                drawingBoard.FillEllipse(&SaddleBrownBrush, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.4), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.4), sizeWheel.X * kx * 0.4, sizeWheel.Y * ky * 0.4);
                drawingBoard.DrawEllipse(&BrushPen, float(centerPointWheel1[i].X - sizeWheel.X * kx / 2 * 0.4), float(centerPointWheel1[i].Y - sizeWheel.Y * ky / 2 * 0.4), sizeWheel.X * kx * 0.4, sizeWheel.Y * ky * 0.4);
            }
            _i += 4;

            g.DrawImage(&backBuffer, rectInstance);
        }
    /* ---------------------- КОНЕЦ ------------------------- */
        else {
            t = -1;
            k_sizeX = 0.6; k_sizeY = 0.6;
            startKeyVector.clear();
            affinMatrix.Reset();
        }
}

...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40043526
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25,

копипаст некачественный ))

надпись выводится только для первого ключевого кадра
а t==0 случается не часто
Код: plaintext
1.
if (stage == 0 && t == 0) {



а это что
Код: plaintext
1.
else if (stage == 1 && 0 <= t <= 1) {

???


вдумчиво перепиши OnDisplay() и настанет счастье
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40044667
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,

я уже решил эту проблему, у меня сейчас проблема осталась только в том что я не могу убрать мерцание (оно только распространяется на саму прорисованную картинку, кроме гифки)

и на третьем кадре применить афинное преобразование, тобишь чтобы оно в процессе перемещения дополнительно еще уменьшалось а потом обратно увеличивалось по характеру графика параболы...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
#include <windows.h>
#include <windowsX.h>
#include <tchar.h>
#include <gdiplus.h>
#include <vector>
#include <gdiplusgraphics.h>    
#include <gdiplusheaders.h>
#include "Math.h"
#pragma comment(lib, "Gdiplus")
#define _USE_MATH_DEFINES
#pragma comment(lib,"Gdiplus.lib")

using namespace Gdiplus;
using namespace std;

Bitmap* imgTextureMetall;
HWND hWnd = NULL;
MSG  msg;
BOOL bRet;
ULONG_PTR           gdiToken;
GdiplusStartupInput gdiStartupInput;
HDC  hdc;
PAINTSTRUCT ps;
//Bitmap* imgTrain = NULL;

/* -- ANIMATION DATA --*/
// массив точек, характеризующие ключевые и промежуточные кадры
std::vector<Gdiplus::PointF> startKeyVector;
Gdiplus::PointF* A;
Gdiplus::PointF* B;
Gdiplus::PointF* P;
Bitmap* imgRoad;
Image* gifTrain;
UINT framesCount;
UINT indexCurrentFrame;
int stage = 0;              // переменная для интерполяции
float t = 0.f;              // параметр для интерполяции
float k_sizeX = 0.6;            // коэффициент масштабирования
float k_sizeY = 0.6;            // коэффициент масштабирования
PointF sizeWheel(70, 70);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

//void DrawProc(HWND);
void OnDisplay(Gdiplus::Graphics& g);
void OnDestroy(HWND hwnd);
void OnDisplay(HDC hdc);
void CopyArrToVector(PointF _array[], std::vector<Gdiplus::PointF>& _vector, int _size);
void CopyPointFToVector(PointF _point, std::vector<Gdiplus::PointF>& _vector);
PointF Tween(const PointF& A, const PointF& B, float t);
void Tween(const PointF* A, const PointF* B, PointF* P, int count, float t);
void IncrementT(int framesCount);
void OnDisplay_Wheels(Graphics& drawingBoard, PointF centerPointWheel, PointF sizeWheel, int wheels, float gap, SolidBrush& Brush1, Pen& Pen1, SolidBrush& Brush2, Pen& Pen2, std::vector<Gdiplus::PointF>& Vector);

int g_step = 0;

int WINAPI _tWinMain(HINSTANCE hInctance, HINSTANCE, LPTSTR lpszCmdLine, int nCmdShow)
{
    ULONG_PTR gdiToken = 0;
    Gdiplus::GdiplusStartupInput gdiStartupInput;
    Gdiplus::GdiplusStartup(&gdiToken, &gdiStartupInput, NULL);

    WNDCLASSEX wc = { sizeof(wc) };
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInctance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = TEXT("MyWindowClass");
    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("Cannot register class"), TEXT("Error"), MB_OK);
        return 0;
    }
    Status stRet = GdiplusStartup(&gdiToken, &gdiStartupInput, NULL);
    imgRoad = new Bitmap(L"road.jpg");
    HWND hWnd = CreateWindow(TEXT("MyWindowClass"), TEXT("MyWindowTitle"), WS_OVERLAPPEDWINDOW, 500, 500, 2000, 1500, 0, 0, hInctance, 0);
    if (hWnd == NULL) {
        return -1;
    }
    imgTextureMetall = new Bitmap(L"texture.jpeg");
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    //MSG msg;
    if (Ok == stRet) {
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (bRet == -1) {
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    Gdiplus::GdiplusShutdown(gdiToken);
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        gifTrain = Image::FromFile(L"Lunohod.gif");
        indexCurrentFrame = 0;
        if (NULL != gifTrain) {
            framesCount = gifTrain->GetFrameCount(&FrameDimensionTime);
        }
        SetTimer(hWnd, 1, 50, 0);
        break;

    case WM_TIMER:
        indexCurrentFrame = (indexCurrentFrame + 1) % framesCount;
        IncrementT(framesCount);
        gifTrain->SelectActiveFrame(&FrameDimensionTime, indexCurrentFrame);
        g_step++;
        InvalidateRect(hWnd, 0, FALSE);
        break;

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        OnDisplay(hdc);
        //DrawProc(hWnd);
        ValidateRect(hWnd, 0);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_ERASEBKGND:								// подавить мерцание
        return 1;

    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

void IncrementT(int framesCount) {
    if (t < 0) {
        stage = 0;
        t = 0;
    }
    else {
        t += (float)1 / framesCount * 3;
        if (t > 1) {
            t = 0;
            stage += 1;
        }
    }
}

void OnDestroy(HWND hwnd) {
    PostQuitMessage(0);
}
void CopyArrToVector(PointF _array[], std::vector<Gdiplus::PointF>& _vector, int _size) {
    for (int i = 0; i < _size; i++) {
        _vector.push_back(_array[i]);
    }
}
void CopyPointFToVector(PointF _point, std::vector<Gdiplus::PointF>& _vector) {
    _vector.push_back(_point);
}

PointF Tween(const PointF& A, const PointF& B, float t) {
    return PointF(A.X * (1.f - t) + B.X * t, A.Y * (1.f - t) + B.Y * t);
}
void Tween(const PointF* A, const PointF* B, PointF* P, int count, float t) {
    for (int g_step = 0; g_step < count; ++g_step) {
        P[g_step] = Tween(A[g_step], B[g_step], t);
    }
}

void OnDisplay_Wheels(Graphics& drawingBoard, PointF centerPointWheel, PointF sizeWheel, int wheels, float gap, SolidBrush& Brush1, Pen& Pen1, SolidBrush& Brush2, Pen& Pen2, std::vector<Gdiplus::PointF>& Vector)
{

}

void OnDisplay(HDC hdc)
{
    Gdiplus::Graphics g(hdc);
    Rect rectInstance;
    g.GetVisibleClipBounds(&rectInstance);
    Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g);
    Graphics drawingBoard(&backBuffer);
    drawingBoard.Clear(Color::White);
    drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);
    drawingBoard.DrawImage(&backBuffer, rectInstance);  // копируем с офлайнового холста на онлайновый
    Matrix affinMatrix;

    // дорога
    TextureBrush textureBrush(imgTextureMetall);
    Pen texturePen(&textureBrush, 15);
    drawingBoard.DrawLine(&texturePen, 0, 1100, 2000, 1100);
    RectF rectim(100.f, 1200.f, 400.f, 200.f);
    drawingBoard.DrawImage(gifTrain, rectim);

    //линейный градиент
    LinearGradientBrush pthGrBrush(Rect(200, 200, 300, 150), Color::White, Color::White, 45.f);
    LinearGradientBrush pthGrBrush2(Rect(200, 200, 300, 150), Color::White, Color::White, 45.f);
    g.DrawImage(&backBuffer, rectInstance);

    P = new PointF[startKeyVector.size()];
    A = new PointF[startKeyVector.size()];
    B = new PointF[startKeyVector.size()];
    for (int g_step = 0; g_step < startKeyVector.size(); ++g_step) {
        A[g_step] = startKeyVector[g_step];
        B[g_step] = startKeyVector[g_step];
    }

    // заставляем крутиться на 360 градусов вокруг точки 
    if (g_step < 50)
    {
        Rect rectInstance;
        g.GetVisibleClipBounds(&rectInstance);
        Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g);
        Graphics drawingBoard(&backBuffer);
        drawingBoard.Clear(Color::White);
        drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);
        drawingBoard.DrawImage(&backBuffer, rectInstance);  // копируем с офлайнового холста на онлайновый
        Matrix affinMatrix;
        g.DrawImage(&backBuffer, rectInstance);

        float angl = 360.f * g_step / 50;
        g.ResetTransform();
        g.TranslateTransform(600.f, 500.f);
        g.RotateTransform(angl);
        Tween(A, B, P, startKeyVector.size(), t);
        OnDisplay(g);
    }

    // заставляем двигаться горизонтально
    else if (g_step < 130)
    {
        Rect rectInstance;
        g.GetVisibleClipBounds(&rectInstance);
        Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g);
        Graphics drawingBoard(&backBuffer);
        drawingBoard.Clear(Color::White);
        drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);
        drawingBoard.DrawImage(&backBuffer, rectInstance);  // копируем с офлайнового холста на онлайновый
        Matrix affinMatrix;
        g.DrawImage(&backBuffer, rectInstance);

        float dist = 5.f * (g_step - 50);
        g.ResetTransform();
        g.TranslateTransform(600.f + dist, 500.f);
        OnDisplay(g);
    }

    // поворачиваем на 30 градусов и заставляем двигаться наклонно
    else if (g_step <= 200)
    {
        Rect rectInstance;
        g.GetVisibleClipBounds(&rectInstance);
        Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g);
        Graphics drawingBoard(&backBuffer);
        drawingBoard.Clear(Color::White);
        drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);
        drawingBoard.DrawImage(&backBuffer, rectInstance);  // копируем с офлайнового холста на онлайновый
        Matrix affinMatrix;
        g.DrawImage(&backBuffer, rectInstance);

        float dist = -5.f * (g_step - 100);
        PointF rotateCenter(850.f, 300.f);
        g.ResetTransform();
        g.RotateTransform(30.f);
        g.TranslateTransform(1650.f, -300.f + dist);
        OnDisplay(g);
    }
}

// рисуем свою картинку в начале координат
void OnDisplay(Gdiplus::Graphics& g)
{
    Rect rectInstance;
    g.GetVisibleClipBounds(&rectInstance);
    Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g);
    Graphics drawingBoard(&backBuffer);
    drawingBoard.Clear(Color::White);
    drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);
    drawingBoard.DrawImage(&backBuffer, rectInstance);  // копируем с офлайнового холста на онлайновый
    Matrix affinMatrix;

    SolidBrush greenBrush(Color(0, 180, 0));
    SolidBrush yellowBrush(Color::Yellow);
    SolidBrush orangeBrush(Color::Orange);
    SolidBrush redBrush(Color(255, 50, 50));
    SolidBrush blackBrush(Color(20, 20, 20));
    HatchBrush hatchBrush(HatchStyleDarkVertical, Color::Silver, Color::Wheat);
    Gdiplus::Pen greenPen(Color(0, 150, 0));
    Gdiplus::Pen redPen(Color(255, 0, 0));
    Gdiplus::Pen blackPen(Color(0, 0, 0));
    Gdiplus::Pen orangePen(Color::Orange);
    Gdiplus::Pen yellowPen(Color::Yellow);
    Gdiplus::Pen WhitePen(Color(255, 255, 255));
    Color colorWhite(Color::White);
    SolidBrush WhiteBrush(Color::White);
    SolidBrush DarkGrayBrush(Color(108, 108, 108));
    SolidBrush BlueBrush(Color(56, 44, 144));
    SolidBrush SaddleBrownBrush(Color(128, 68, 4));
    SolidBrush BrunBrown(Color(68, 36, 4));
    SolidBrush DarkTurquoiseBrown(Color(0, 206, 209));
    SolidBrush DarkCyanBrown(Color(0, 139, 139));
    Gdiplus::Pen BrushPen(Color(68, 36, 4));
    Gdiplus::Pen BluePen(Color(56, 44, 144));
    Color windowsColors[4] = {
        Color::MediumTurquoise,
        Color::SkyBlue,
        Color::MediumTurquoise,
        Color::SteelBlue,
    };
    Color colors[3] = { Color(255, 0, 255, 255), Color(255, 0, 155, 155), Color(255, 0, 0, 0) };
    float pos[3] = { 0.0f, 0.3f, 1.0f };
    Color colors1[3] = { Color(255, 0, 255, 255), Color(255, 0, 155, 155), Color(255, 0, 0, 0) };
    float pos1[3] = { 0.0f, 0.3f, 1.0f };
    int n = 4;
    int wheels = 4; // кол-во колес

    //составное перо
    Pen CompPen(Color::Black, 6.f);
    float comp[6] = { 0.0f, 0.2f, 0.3f, 0.7f, 0.8f, 1.0f };
    CompPen.SetCompoundArray(comp, 6);
    WrapMode wrapMode = WrapModeTile;

    //голубой корпус
    PointF points[4] = { PointF(190, 410), PointF(150, 310), PointF(450, 310), PointF(400, 410) };
    // +4
    CopyArrToVector(points, startKeyVector, 4);
    g.FillPolygon(&DarkTurquoiseBrown, points, 4);
    g.DrawPolygon(&blackPen, points, 4);

    //оконтовочный бортик (голубой)
    PointF pointsa[4] = { PointF(120, 300), PointF(480, 300), PointF(480, 320), PointF(120, 320) };
    // +4
    CopyArrToVector(pointsa, startKeyVector, 4);
    g.FillPolygon(&DarkCyanBrown, pointsa, 4);
    g.DrawPolygon(&blackPen, pointsa, 4);

    //серая антенна
    PointF pointsb[4] = { PointF(350, 300), PointF(510, 140), PointF(513, 143), PointF(355, 300) };
    // +4
    CopyArrToVector(pointsb, startKeyVector, 4);
    g.FillPolygon(&DarkGrayBrush, pointsb, 4);
    g.DrawPolygon(&blackPen, pointsb, 4);
    g.DrawCurve(&CompPen, pointsb, 4);

    //линейный градиент 1
    PointF windowsPoints[5] = { PointF(190, 410), PointF(150, 310), PointF(295, 410), PointF(450, 310), PointF(400, 410) };
    CopyArrToVector(windowsPoints, startKeyVector, 5);
    // +4
    PointF centerPointWindow(295, 410);  // координаты центра для окна
    // +1
    PathGradientBrush pthGrBrush(windowsPoints, 5); // кисть градиента контура
    pthGrBrush.SetCenterPoint(centerPointWindow);
    pthGrBrush.SetInterpolationColors(colors, pos, 5);
    pthGrBrush.SetSurroundColors(windowsColors, &n);
    g.FillPolygon(&pthGrBrush, windowsPoints, 5);
    g.DrawPolygon(&blackPen, windowsPoints, 5);

    // Надпись
    Font font(L"Courier", 25.f, FontStyleBold);
    g.DrawString(L"СССР", -1, &font, PointF(250, 330), &SaddleBrownBrush);

    // Эллипсы
    g.RotateTransform(-30);
    g.TranslateTransform(0.0f, 0.0f);
    g.DrawEllipse(&BrushPen, -110, 25, 150, 300);
    g.FillEllipse(&BlueBrush, -110, 25, 150, 300);
    g.RotateTransform(68);
    g.DrawEllipse(&BrushPen, 435, -45, 70, 30);
    g.FillEllipse(&DarkGrayBrush, 435, -45, 70, 30);
    g.DrawEllipse(&BrushPen, 444, -75, 60, 26);
    g.FillEllipse(&DarkGrayBrush, 444, -75, 60, 26);
    g.DrawEllipse(&BrushPen, 453, -100, 50, 22);
    g.FillEllipse(&DarkGrayBrush, 453, -100, 50, 22);
    g.DrawEllipse(&BrushPen, 461, -120, 40, 18);
    g.FillEllipse(&DarkGrayBrush, 461, -120, 40, 18);
    g.DrawEllipse(&BrushPen, 468, -136, 30, 14);
    g.FillEllipse(&DarkGrayBrush, 468, -136, 30, 14);

    g.RotateTransform(0); //Колеса
    // Колесо1
    g.RotateTransform(0);
    g.DrawEllipse(&BrushPen, 375, 200, 70, 70);
    g.FillEllipse(&SaddleBrownBrush, 375, 200, 70, 70);
    g.DrawEllipse(&BrushPen, 390, 215, 40, 40);
    g.FillEllipse(&WhiteBrush, 390, 215, 40, 40);
    g.DrawEllipse(&BrushPen, 397.5, 222.5, 25, 25);
    g.FillEllipse(&BrunBrown, 397.5, 222.5, 25, 25);
    // Колесо2
    g.DrawEllipse(&BrushPen, 435, 155, 70, 70);
    g.FillEllipse(&SaddleBrownBrush, 435, 155, 70, 70);
    g.DrawEllipse(&BrushPen, 450, 170, 40, 40);
    g.FillEllipse(&WhiteBrush, 450, 170, 40, 40);
    g.DrawEllipse(&BrushPen, 457.5, 177.5, 25, 25);
    g.FillEllipse(&BrunBrown, 457.5, 177.5, 25, 25);
    // Колесо3
    g.DrawEllipse(&BrushPen, 495, 110, 70, 70);
    g.FillEllipse(&SaddleBrownBrush, 495, 110, 70, 70);
    g.DrawEllipse(&BrushPen, 510, 125, 40, 40);
    g.FillEllipse(&WhiteBrush, 510, 125, 40, 40);
    g.DrawEllipse(&BrushPen, 517.5, 132.5, 25, 25);
    g.FillEllipse(&BrunBrown, 517.5, 132.5, 25, 25);
    // Колесо4
    g.DrawEllipse(&BrushPen, 555, 65, 70, 70);
    g.FillEllipse(&SaddleBrownBrush, 555, 65, 70, 70);
    g.DrawEllipse(&BrushPen, 570, 80, 40, 40);
    g.FillEllipse(&WhiteBrush, 570, 80, 40, 40);
    g.DrawEllipse(&BrushPen, 577.5, 87.5, 25, 25);
    g.FillEllipse(&BrunBrown, 577.5, 87.5, 25, 25);
    g.TranslateTransform(0.0f, 0.0f);
}

...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40044712
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25,
Если мерцает, то смотреть частоту кадров и вывод в буфер за экраном и потом быстрое переключение. Плюс XOR.
Если анимацию добавлять, то уже будет месиво. Надо ООП подключать.
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40044922
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25, дружище. Твой код желательно отрефакторить. Очень много копи-пасты по прежнему остается.
Сложно сопровождать и исправлять ошибки когда логика в нескольких местах. Возникает много вопросов
типа "это одна и та-же логика" или "похожая" и т.д.

Не пренебрегай рефакторингом даже в учебных проектах.
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40044974
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton,

mayton
Очень много копи-пасты по прежнему остается.
не отрицаю....

mayton
Твой код желательно отрефакторить.
время время время... я еще не силен в c++ ... все по аналогии делаю, сложно еще ...

по идее у меня мерцание должно было исчезнуть при изменении с g1 на drawingBoard

в секторе
Код: plaintext
1.
OnDisplay(Gdiplus::Graphics& g1)

где FillPolygon и DrawPolygon прописываются

но вместо этого - у меня просто все исчезает!

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
#include <windows.h>
#include <windowsX.h>
#include <tchar.h>
#include <gdiplus.h>
#include <vector>
#include <gdiplusgraphics.h>    
#include <gdiplusheaders.h>
#include "Math.h"
#pragma comment(lib, "Gdiplus")
#define _USE_MATH_DEFINES
#pragma comment(lib,"Gdiplus.lib")

using namespace Gdiplus;
using namespace std;

Bitmap* imgTextureMetall;
HWND hWnd = NULL;
MSG  msg;
BOOL bRet;
ULONG_PTR           gdiToken;
GdiplusStartupInput gdiStartupInput;
HDC  hdc;
PAINTSTRUCT ps;
//Bitmap* imgTrain = NULL;

/* -- ANIMATION DATA --*/
// массив точек, характеризующие ключевые и промежуточные кадры
std::vector<Gdiplus::PointF> startKeyVector;
Gdiplus::PointF* A;
Gdiplus::PointF* B;
Gdiplus::PointF* P;
Bitmap* imgRoad;
Image* gifTrain;
UINT framesCount;
UINT indexCurrentFrame;
int stage = 0;              // переменная для интерполяции
float t = 0.f;              // параметр для интерполяции
float k_sizeX = 0.6;            // коэффициент масштабирования
float k_sizeY = 0.6;            // коэффициент масштабирования
PointF sizeWheel(70, 70);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

void OnDisplay(Gdiplus::Graphics& g);
void OnDestroy(HWND hwnd);
void OnDisplay(HDC hdc);
void CopyArrToVector(PointF _array[], std::vector<Gdiplus::PointF>& _vector, int _size);
void CopyPointFToVector(PointF _point, std::vector<Gdiplus::PointF>& _vector);
PointF Tween(const PointF& A, const PointF& B, float t);
void Tween(const PointF* A, const PointF* B, PointF* P, int count, float t);
void IncrementT(int framesCount);
void OnDisplay_Wheels(Graphics& drawingBoard, PointF centerPointWheel, PointF sizeWheel, int wheels, float gap, SolidBrush& Brush1, Pen& Pen1, SolidBrush& Brush2, Pen& Pen2, std::vector<Gdiplus::PointF>& Vector);

int g_step = 0;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ULONG_PTR gdiToken = 0;
    Gdiplus::GdiplusStartupInput gdiStartupInput;
    Gdiplus::GdiplusStartup(&gdiToken, &gdiStartupInput, NULL);

    WNDCLASSEX wc = { sizeof(wc) };
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = TEXT("MyWindowClass");
    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, TEXT("Cannot register class"), TEXT("Error"), MB_OK);
        return 0;
    }
    Status stRet = GdiplusStartup(&gdiToken, &gdiStartupInput, NULL);
    imgRoad = new Bitmap(L"Lune.jpg");
    HWND hWnd = CreateWindow(TEXT("MyWindowClass"), TEXT("MyWindowTitle"), WS_OVERLAPPEDWINDOW, 500, 500, 2000, 1500, 0, 0, hInstance, 0);
    if (!hWnd)
    {
        MessageBox(NULL, TEXT("Cannot create main window"), TEXT("Error"), MB_OK);
        return 0;
    }
    imgTextureMetall = new Bitmap(L"texture.jpeg");
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    MSG msg;
    if (Ok == stRet) {
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (bRet == -1) {
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    Gdiplus::GdiplusShutdown(gdiToken);
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_ERASEBKGND: // подавить мерцание
        return 1;

    case WM_CREATE:
        gifTrain = Image::FromFile(L"Lunohod.gif");
        indexCurrentFrame = 0;
        if (NULL != gifTrain) {
            framesCount = gifTrain->GetFrameCount(&FrameDimensionTime);
        }
        SetTimer(hWnd, 1, 100, 0);
        break;

    case WM_TIMER:
        indexCurrentFrame = (indexCurrentFrame + 1) % framesCount;
        IncrementT(framesCount);
        gifTrain->SelectActiveFrame(&FrameDimensionTime, indexCurrentFrame);
        g_step++;
        InvalidateRect(hWnd, 0, FALSE);
        break;

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        OnDisplay(hdc);
        ValidateRect(hWnd, 0);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

void IncrementT(int framesCount) {
    if (t < 0) {
        stage = 0;
        t = 0;
    }
    else {
        t += (float)1 / framesCount * 3;
        if (t > 1) {
            t = 0;
            stage += 1;
        }
    }
}

void OnDestroy(HWND hwnd) {
    PostQuitMessage(0);
}
void CopyArrToVector(PointF _array[], std::vector<Gdiplus::PointF>& _vector, int _size) {
    for (int i = 0; i < _size; i++) {
        _vector.push_back(_array[i]);
    }
}
void CopyPointFToVector(PointF _point, std::vector<Gdiplus::PointF>& _vector) {
    _vector.push_back(_point);
}

void OnDisplay_Wheels(Graphics& drawingBoard, PointF centerPointWheel, PointF sizeWheel, int wheels, float gap, SolidBrush& Brush1, Pen& Pen1, SolidBrush& Brush2, Pen& Pen2, std::vector<Gdiplus::PointF>& Vector)
{
}


// рисуем свою картинку в начале координат
void OnDisplay(Gdiplus::Graphics& g1)
{
    Rect rectInstance;
    g1.GetVisibleClipBounds(&rectInstance);
    Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g1);
    Graphics drawingBoard(&backBuffer);
    drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);

    SolidBrush greenBrush(Color(0, 180, 0));
    SolidBrush yellowBrush(Color::Yellow);
    SolidBrush orangeBrush(Color::Orange);
    SolidBrush redBrush(Color(255, 50, 50));
    SolidBrush blackBrush(Color(20, 20, 20));
    HatchBrush hatchBrush(HatchStyleDarkVertical, Color::Silver, Color::Wheat);
    Gdiplus::Pen greenPen(Color(0, 150, 0));
    Gdiplus::Pen redPen(Color(255, 0, 0));
    Gdiplus::Pen blackPen(Color(0, 0, 0));
    Gdiplus::Pen orangePen(Color::Orange);
    Gdiplus::Pen yellowPen(Color::Yellow);
    Gdiplus::Pen WhitePen(Color(255, 255, 255));
    Color colorWhite(Color::White);
    SolidBrush WhiteBrush(Color::White);
    SolidBrush DarkGrayBrush(Color(108, 108, 108));
    SolidBrush BlueBrush(Color(56, 44, 144));
    SolidBrush SaddleBrownBrush(Color(128, 68, 4));
    SolidBrush BrunBrown(Color(68, 36, 4));
    SolidBrush DarkTurquoiseBrown(Color(0, 206, 209));
    SolidBrush DarkCyanBrown(Color(0, 139, 139));
    Gdiplus::Pen BrushPen(Color(68, 36, 4));
    Gdiplus::Pen BluePen(Color(56, 44, 144));
    Color windowsColors[4] = {
        Color::MediumTurquoise,
        Color::SkyBlue,
        Color::MediumTurquoise,
        Color::SteelBlue,
    };
    Color colors[3] = { Color(255, 0, 255, 255), Color(255, 0, 155, 155), Color(255, 0, 0, 0) };
    float pos[3] = { 0.0f, 0.3f, 1.0f };
    Color colors1[3] = { Color(255, 0, 255, 255), Color(255, 0, 155, 155), Color(255, 0, 0, 0) };
    float pos1[3] = { 0.0f, 0.3f, 1.0f };
    int n = 4;

    //составное перо
    Pen CompPen(Color::Black, 6.f);
    float comp[6] = { 0.0f, 0.2f, 0.3f, 0.7f, 0.8f, 1.0f };
    CompPen.SetCompoundArray(comp, 6);


    //голубой корпус
    PointF points[4] = { PointF(190, 410), PointF(150, 310), PointF(450, 310), PointF(400, 410) };
    // +4
    CopyArrToVector(points, startKeyVector, 4);
    g1.FillPolygon(&DarkTurquoiseBrown, points, 4);
    g1.DrawPolygon(&blackPen, points, 4);

    //оконтовочный бортик (голубой)
    PointF pointsa[4] = { PointF(120, 300), PointF(480, 300), PointF(480, 320), PointF(120, 320) };
    // +4
    CopyArrToVector(pointsa, startKeyVector, 4);
    g1.FillPolygon(&DarkCyanBrown, pointsa, 4);
    g1.DrawPolygon(&blackPen, pointsa, 4);

    //серая антенна
    PointF pointsb[4] = { PointF(350, 300), PointF(510, 140), PointF(513, 143), PointF(355, 300) };
    // +4
    CopyArrToVector(pointsb, startKeyVector, 4);
    g1.FillPolygon(&DarkGrayBrush, pointsb, 4);
    g1.DrawPolygon(&blackPen, pointsb, 4);
    g1.DrawCurve(&CompPen, pointsb, 4);

    //линейный градиент 1
    PointF windowsPoints[5] = { PointF(190, 410), PointF(150, 310), PointF(295, 410), PointF(450, 310), PointF(400, 410) };
    CopyArrToVector(windowsPoints, startKeyVector, 5);
    PointF centerPointWindow(295, 410);  // координаты центра для окна
    PathGradientBrush pthGrBrush(windowsPoints, 5); // кисть градиента контура
    pthGrBrush.SetCenterPoint(centerPointWindow);
    pthGrBrush.SetInterpolationColors(colors, pos, 5);
    pthGrBrush.SetSurroundColors(windowsColors, &n);
    g1.FillPolygon(&pthGrBrush, windowsPoints, 5);
    g1.DrawPolygon(&blackPen, windowsPoints, 5);

    // Надпись
    Font font(L"Courier", 25.f, FontStyleBold);
    g1.DrawString(L"СССР", -1, &font, PointF(250, 330), &SaddleBrownBrush);

    // Эллипсы
    g1.RotateTransform(-30);
    g1.TranslateTransform(0.0f, 0.0f);
    g1.DrawEllipse(&BrushPen, -110, 25, 150, 300);
    g1.FillEllipse(&BlueBrush, -110, 25, 150, 300);
    g1.RotateTransform(68);
    g1.DrawEllipse(&BrushPen, 435, -45, 70, 30);
    g1.FillEllipse(&DarkGrayBrush, 435, -45, 70, 30);
    g1.DrawEllipse(&BrushPen, 444, -75, 60, 26);
    g1.FillEllipse(&DarkGrayBrush, 444, -75, 60, 26);
    g1.DrawEllipse(&BrushPen, 453, -100, 50, 22);
    g1.FillEllipse(&DarkGrayBrush, 453, -100, 50, 22);
    g1.DrawEllipse(&BrushPen, 461, -120, 40, 18);
    g1.FillEllipse(&DarkGrayBrush, 461, -120, 40, 18);
    g1.DrawEllipse(&BrushPen, 468, -136, 30, 14);
    g1.FillEllipse(&DarkGrayBrush, 468, -136, 30, 14);

    g1.RotateTransform(0); //Колеса
    // Колесо1
    g1.RotateTransform(0);
    g1.DrawEllipse(&BrushPen, 375, 200, 70, 70);
    g1.FillEllipse(&SaddleBrownBrush, 375, 200, 70, 70);
    g1.DrawEllipse(&BrushPen, 390, 215, 40, 40);
    g1.FillEllipse(&WhiteBrush, 390, 215, 40, 40);
    g1.DrawEllipse(&BrushPen, 397.5, 222.5, 25, 25);
    g1.FillEllipse(&BrunBrown, 397.5, 222.5, 25, 25);
    // Колесо2
    g1.DrawEllipse(&BrushPen, 435, 155, 70, 70);
    g1.FillEllipse(&SaddleBrownBrush, 435, 155, 70, 70);
    g1.DrawEllipse(&BrushPen, 450, 170, 40, 40);
    g1.FillEllipse(&WhiteBrush, 450, 170, 40, 40);
    g1.DrawEllipse(&BrushPen, 457.5, 177.5, 25, 25);
    g1.FillEllipse(&BrunBrown, 457.5, 177.5, 25, 25);
    // Колесо3
    g1.DrawEllipse(&BrushPen, 495, 110, 70, 70);
    g1.FillEllipse(&SaddleBrownBrush, 495, 110, 70, 70);
    g1.DrawEllipse(&BrushPen, 510, 125, 40, 40);
    g1.FillEllipse(&WhiteBrush, 510, 125, 40, 40);
    g1.DrawEllipse(&BrushPen, 517.5, 132.5, 25, 25);
    g1.FillEllipse(&BrunBrown, 517.5, 132.5, 25, 25);
    // Колесо4
    g1.DrawEllipse(&BrushPen, 555, 65, 70, 70);
    g1.FillEllipse(&SaddleBrownBrush, 555, 65, 70, 70);
    g1.DrawEllipse(&BrushPen, 570, 80, 40, 40);
    g1.FillEllipse(&WhiteBrush, 570, 80, 40, 40);
    g1.DrawEllipse(&BrushPen, 577.5, 87.5, 25, 25);
    g1.FillEllipse(&BrunBrown, 577.5, 87.5, 25, 25);
    g1.TranslateTransform(0.0f, 0.0f);
}

void OnDisplay(HDC hdc)
{
    Graphics g1(hdc);
    Rect rectInstance;
    g1.GetVisibleClipBounds(&rectInstance);
    Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g1);
    Graphics drawingBoard(&backBuffer);
    drawingBoard.DrawImage(imgRoad, rectInstance);

    // дорога
    TextureBrush textureBrush(imgTextureMetall);
    Pen texturePen(&textureBrush, 30);
    drawingBoard.DrawLine(&texturePen, 0, 1100, 2000, 1100);
    RectF rectim(100.f, 1200.f, 400.f, 200.f);
    drawingBoard.DrawImage(gifTrain, rectim);

    //линейный градиент
    LinearGradientBrush pthGrBrush(Rect(200, 200, 300, 150), Color::White, Color::White, 45.f);
    g1.DrawImage(&backBuffer, rectInstance);

    // заставляем крутиться на 360 градусов вокруг точки 
    if (g_step < 50)
    {
        float angl = 360.f * g_step / 50;
        g1.ResetTransform();
        g1.TranslateTransform(600.f, 500.f);
        g1.RotateTransform(angl);
        OnDisplay(g1);
    }

    // заставляем двигаться горизонтально
    else if (g_step < 130)
    {
        float dist = 5.f * (g_step - 50);
        g1.ResetTransform();
        g1.TranslateTransform(600.f + dist, 500.f);
        OnDisplay(g1);
    }

    // поворачиваем на 30 градусов и заставляем двигаться наклонно
    else if (g_step <= 200)
    {
        float dist = -5.f * (g_step - 100);
        PointF rotateCenter(850.f, 300.f);
        g1.ResetTransform();
        g1.RotateTransform(30.f);
        g1.TranslateTransform(1650.f, -300.f + dist);
        OnDisplay(g1);
    }
}

...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045198
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25
но вместо этого - у меня просто все исчезает!

напиши с чистого листа самый простой код OnDisplay
без оптимизации типа GetVisibleClipBounds,
погоняй простое изображение по экрану

Мерцание/дрожание всё равно останется - Gdi+ - не лучший инструмент для анимации,
рассмотри OpenGL
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045203
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,

у меня gdi+ по заданию требуется использовать
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045206
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25у меня gdi+ по заданию требуется использовать

Тогда не заливай background, мерцать будет нечему.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045208
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

да вот фон и гифка у меня то не мерцают!!!

у меня само растровое изображение мерцает
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045210
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25у меня само растровое изображение мерцает

Потому что оно слишком долго рисуется и от WM_ERASEBACKGROUND до полного его вывода
проходит больше 0,03 секунды. Как уже сказали: начни с нуля и постепенно увеличивай
количество элементов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045212
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov,

Я не допонимаю ... Это как "постепенно увеличивай"???
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045213
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25Это как "постепенно увеличивай"???

Начни с одного колеса. Как только оно будет нормально работать - добавишь второе.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045215
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25
Dimitry Sibiryakov,

Я не допонимаю ... Это как "постепенно увеличивай"???

бить код на куски. Ключевые слова - паттерны программирования\ООП\модульность.
Функция void OnDisplay(HDC hdc) {
не должна быть 1500 строк кода.
Она должна влазить в экран монитора.
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045218
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25
Код: sql
1.
2.
3.
4.
5.
6.
// рисуем свою картинку в начале координат
void  OnDisplay(Gdiplus::Graphics& g1)
{
      Rect rectInstance;
      g1.GetVisibleClipBounds(&rectInstance);
      Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g1);


Давай прикинемся, что я не знаю GDI+, а ты его знаешь. И я задаю вопрос новичка: что
делает backBuffer и зачем он тут нужен?
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045317
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25
но вместо этого - у меня просто все исчезает!
У вас какая-то полная хрень с double buffering. Если делать это вручную, то сначала рисуем всё в back buffer, потом одним махом копируем содержимое back buffer-а в окно. Чего в вашем коде не наблюдается. Попробуйте для начала выкинуть свою реализацию double buffering (объекты backBuffer, drawingBoard) и просто указывайте extended style WS_EX_COMPOSITED при создании окна.

xamelione25
у меня gdi+ по заданию требуется использовать
Странно. Я просто не понимаю, зачем нужен GDI+. Если нужна простенькая графика (прямоугольники, текст, растровые картинки), то GDI хватит. Если надо отрисовывать анимации с частотой 50-60 кадров в секунду на большие pixel-ные площади, то надо использовать графический API с аппаратным ускорением: OpenGL или Direct3D. В таких API есть операция типа «нарисовать пачку текстурированных треугольников» (реализованная в видео-карте), и обычно вся графика строится на базе этой операции (как в играх например). Если нужна какая-то серьёзная векторная графика, то имеет смысл использовать библиотеки типа Cairo или AGG. В Qt что-то есть. А вот зачем нужен GDI+ -- не понимаю.

xamelione25
Код: plaintext
1.
    g1.DrawString(L"СССР", -1, &font, PointF(250, 330), &SaddleBrownBrush);

Какая у вас ЭВМ, товарищ? Искра?
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045335
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пётр Седов,

можете мне показать на примере как повернуть эллипс - у меня особая сложность возникает в повороте эллипса в анимации
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045565
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25,

ущербна идея вместо поворота и сдвига системы координат вычислять координаты отрезков,вершин полигонов и центров окружностей (affinMatrix.TransformPoints) и затем интерполировать координаты (Tween)

выбросьте чужой многократно скопипащеный с массой ошибок код
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045604
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дружище xamelione25.

Я подытожу общее мнение форума. Скорее всего оно - works as designed - работает как запрограммировано.
А как оно должно работать по заданию никто-ж не знает. А сведенья ты дал скудные. Без иллюстраций
и чертежей.

Дам совет. Уже не из области разработки а скорее из тестирования и трабл-шутинга.

Выброси из кода (закомментарь) логику которая ломает траекторию фигур. В ней нет гладкости и фигуры
могут столь резко дергаться и вылетать за границы кадра что ошибка будет иметь совсем
другую природу.

Вот это

Код: plaintext
1.
if (g_step < 50) ..... 



Проверь у себя и докажи что логика корректна хотя-бы для 1 типа движения и дальше уже перейдем к другим
траекториям.
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045612
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

не усложняй, как должно работать по заданию - понятно, луноход с крышкой должен вращаться(перемещение без поворта работает коррентно, хотя код хочется развидеть)


Нет в этом коде вращения фигур, есть вычисление координат вершин полигонов, нет фигуры как объекта
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045639
Пётр Седов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xamelione25, я попробовал заменить CreateWindow на CreateWindowEx и указать первым параметром WS_EX_COMPOSITED, но чего-то double buffering нормально не заработал. Поэтому можно сделать вручную:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
...
void OnDisplay(HDC hdc, Rect paintBounds); // дополнительный параметр
...
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    ...
    case WM_PAINT:
    {
        // ps и hdc лучше делать локальными переменными
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        Rect paintBounds;
        paintBounds.X = ps.rcPaint.left;
        paintBounds.Y = ps.rcPaint.top;
        paintBounds.Width = ps.rcPaint.right - ps.rcPaint.left;
        paintBounds.Height = ps.rcPaint.bottom - ps.rcPaint.top;
        OnDisplay(hdc, paintBounds);
        EndPaint(hWnd, &ps);
        break;
    }
    ...
}
...
// рисуем свою картинку в начале координат
void OnDisplay(Gdiplus::Graphics& g1)
{
    // это всё не нужно, убираем
    //Rect rectInstance;
    //g1.GetVisibleClipBounds(&rectInstance);
    //Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g1);
    //Graphics drawingBoard(&backBuffer);
    //drawingBoard.SetSmoothingMode(SmoothingModeAntiAlias);

    // остальное без изменений, рисуем на g1
    ...
}

void OnDisplay(HDC hdc, Rect paintBounds)
{
    Graphics g1(hdc);
    Bitmap backBuffer(paintBounds.Width, paintBounds.Height, &g1);
    Graphics drawingBoard(&backBuffer);
    drawingBoard.TranslateTransform(-paintBounds.X, -paintBounds.Y);
    drawingBoard.DrawImage(imgRoad, Rect(0, 0, 2123, 2123)); // координаты от балды

    // дорога
    TextureBrush textureBrush(imgTextureMetall);
    Pen texturePen(&textureBrush, 30);
    drawingBoard.DrawLine(&texturePen, 0, 1100, 2000, 1100);
    RectF rectim(100.f, 1200.f, 400.f, 200.f);
    drawingBoard.DrawImage(gifTrain, rectim);

    //линейный градиент
    LinearGradientBrush pthGrBrush(Rect(200, 200, 300, 150), Color::White, Color::White, 45.f);
    drawingBoard.DrawImage(&backBuffer, Rect(0, 0, 2123, 2123)); // координаты от балды

    // заставляем крутиться на 360 градусов вокруг точки 
    if (g_step < 50)
    {
        float angl = 360.f * g_step / 50;
        // не надо drawingBoard.ResetTransform()
        drawingBoard.TranslateTransform(600.f, 500.f);
        drawingBoard.RotateTransform(angl);
        OnDisplay(drawingBoard);
    }

    // заставляем двигаться горизонтально
    else if (g_step < 130)
    {
        float dist = 5.f * (g_step - 50);
        // не надо drawingBoard.ResetTransform()
        drawingBoard.TranslateTransform(600.f + dist, 500.f);
        OnDisplay(drawingBoard);
    }

    // поворачиваем на 30 градусов и заставляем двигаться наклонно
    else if (g_step <= 200)
    {
        float dist = -5.f * (g_step - 100);
        PointF rotateCenter(850.f, 300.f);
        // не надо drawingBoard.ResetTransform()
        drawingBoard.RotateTransform(30.f);
        drawingBoard.TranslateTransform(1650.f, -300.f + dist);
        OnDisplay(drawingBoard);
    }

    drawingBoard.Flush(FlushIntentionSync); // может, и не нужно; хрен его знает
    g1.DrawImage(&backBuffer, paintBounds.X, paintBounds.Y);
}

Back buffer должен быть один единственный на время отрисовки.

GDI+ кстати не самый худший вариант для обучения. Могли бы заставить делать что-нибудь на Borland-овском BGI :).

xamelione25
можете мне показать на примере как повернуть эллипс - у меня особая сложность возникает в повороте эллипса в анимации
А в чём проблема с эллипсами? У меня вроде всё нормально рисуется:
...
Рейтинг: 0 / 0
Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
    #40045640
xamelione25
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пётр Седов,

Вопрос уже решен!!! Там был вопрос в том что у меня при запуске анимации в первом варианте было мерцание (там рисовался рисунок, а потом производились с ним анимационные манипуляции), а в другом варианте было то что не эллипс не разворачивался синхронно в процессе анимации вместе с остальными элементами.

Сейчас остался вопрос только в том как сделать не последовательное выполнение анимационных эффектов, а параллельное

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
void OnDisplay(HDC hdc)
{
    Graphics g1(hdc);
    Rect rectInstance;
    g1.GetVisibleClipBounds(&rectInstance);
    Bitmap backBuffer(rectInstance.Width, rectInstance.Height, &g1);
    Graphics drawingBoard(&backBuffer);
    drawingBoard.DrawImage(imgRoad, rectInstance);
    //Matrix affinMatrix;
    // дорога
    TextureBrush textureBrush(imgTextureMetall);
    Pen texturePen(&textureBrush, 30);
    drawingBoard.DrawLine(&texturePen, 0, 1100, 2000, 1100);
    RectF rectim(100.f, 1200.f, 400.f, 200.f);
    drawingBoard.DrawImage(gifTrain, rectim);

    //линейный градиент
    LinearGradientBrush pthGrBrush(Rect(200, 200, 300, 150), Color::White, Color::White, 45.f);

    // заставляем крутиться на 360 градусов вокруг точки 
    if (g_step < 50)
    {
        float angl = 360.f * g_step / 50;
        drawingBoard.ResetTransform();
        drawingBoard.TranslateTransform(700.f, 500.f);
        drawingBoard.RotateTransform(angl);
        OnDisplay(drawingBoard);
    }

    // заставляем двигаться горизонтально
    else if (g_step < 100)
    {
        float dist = 5.f * (g_step - 50);
        drawingBoard.TranslateTransform(700.f + dist, 500.f);
        OnDisplay(drawingBoard);
    }

    // поворачиваем на 30 градусов и заставляем двигаться наклонно
    else if (g_step < 150)
    {
        float dist = 5.f * (g_step - 100);
        drawingBoard.ResetTransform();
        drawingBoard.TranslateTransform(950.f + dist, 500.f - dist);
        //drawingBoard.RotateTransform(g_step);
        drawingBoard.ScaleTransform(1+dist/1000, 1+dist/1000);

        OnDisplay(drawingBoard);
    }

    else if (g_step < 200)
    {
        float dist = 5.f * (g_step - 100);
        drawingBoard.ResetTransform();
        drawingBoard.TranslateTransform(700.f + dist, 500.f);
        drawingBoard.ScaleTransform(-3 + dist/100, -3 + dist/100);
        drawingBoard.RotateTransform(100.f + g_step);
        drawingBoard.TranslateTransform(-250, -40);
        OnDisplay(drawingBoard);
    }

    else if (g_step = 200)
    {
        g_step = -1;
        startKeyVector.clear();
        drawingBoard.ResetTransform();
    }

    g1.DrawImage(&backBuffer, rectInstance);
}



Мне нужно, чтобы анимационные эффекты, которые приписаны в 3 и 4 кадрах, отображались все совместно, а не друг за другом - последовательно
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Поворот эллипса в аннимации RotateTransform. Афинные преобразования GDI+. Поворот надписи
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]