singlepost

Помогите с графикой под WinAPI << На главную или назад  

Помогите, пожалуйста:)
Мне нужно нарисовать правильный шестиугольник, не могу составить цикл и разобраться с ошибками…
Буду очень благодарна. Заранее спасибо.

#include <windows.h>
//#include "resource.h"
#include <math.h>

HINSTANCE hInst;
char szAppName[] ="ApiWin";
char szTitle[] ="Window Application";

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

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASSEX wc;
HWND hwnd;
hInst=hInstance;
memset(&wc,0,sizeof(wc));
wc.style=CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc= (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance= hInst;
//wc.hIcon=(HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,32,32,0);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName= NULL;
wc.lpszClassName = szAppName;
wc.cbSize=sizeof(WNDCLASSEX);
//wc.hIconSm=LoadImage(hInst,MAKEINTRESOURCE(IDI_APPICON_SM),IMAGE_ICON,16,16,0);

if(!RegisterClassEx(&wc))
return FALSE;

hwnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInst, NULL);

if (!hwnd)
return (FALSE);

ShowWindow(hwnd, nCmdShow);

UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}

int x=50;
int y=50;
float CD=0;
int dist=20;
float angle = 30;

void turnTo(float angle)
{
angle=CD;
return;
}
voidturn(float angle)
{
CD+=angle;
return;
}
void forward(int dist)
{
const float RadPerDeg=0.01745339;
int x=x+dist*cos(RadPerDeg*CD);
int y=y+dist*sin(RadPerDeg*CD);
HDC hdc;
LineTo(hdc,x,y);

POINT A;
A.x=100;
A.y=100;
POINT FAR* lppt=&A;
MoveToEx(hdc,x,y,lppt);
return;
}

LRESULT CALLBACK WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static short cxClient, cyClient;
PAINTSTRUCT ps;
HDC hdc;

switch (message)
{
case WM_SIZE:
{
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
}
case WM_PAINT:
{
hdc=BeginPaint(hwnd,&ps);
HGDIOBJ hPen=CreatePen(PS_DASH, 5, RGB(0,255,100));
HGDIOBJ hOldPen=SelectObject(hdc,hPen);

turnTo(angle);
turn(angle);
forward(dist);

EndPaint(hwnd,&ps);
break;
}

case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hwnd, message, wParam, lParam));
}
return (0);
}

54 ответов в теме “Помогите с графикой под WinAPI”

  1. 49
    Kitt Wasserfall ответил:

    Сама – это правильно.

  2. 48
    Альбинка Шакирзянова ответил:

    Да я уже сделала)) правда через angle так и не получилось, пришлось фиксировать конкретное CD для каждого шага. Но препод сказал что пойдет и так)

  3. 47
    Kitt Wasserfall ответил:

    В выходные напомни в личку, если сама не разберёшься, я сейчас не могу, у меня тут только Apple со всеми вытекающими – нет WinApi.

  4. 46
    Альбинка Шакирзянова ответил:

    помоги плиз еще раз)) я сейчас другой меандр рисую. где i=3 мне надо чтобы линия шла наверх а не вниз, но как бы угол не меняла все вниз идет. Почему не знаешь?

    for(int k=0; k<1; k++) //количество повторений
    {
    int CD=0;
    int angle=90;
    int len;
    int dist=len=160;
    for (int i=0; i<4; i++) //ходы
    {
    if(i<2)
    {
    dist=len/2;
    }
    else if(i==2)
    {
    dist=len/4;
    }
    else if(i==3)
    {
    angle=-90;
    }
    x=x+dist*cos(0.017453393*CD);
    y=y+dist*sin(0.017453393*CD);
    LineTo(hdc,x,y);
    CD-=angle;
    POINT A;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);
    }

    }

  5. 45
    Kitt Wasserfall ответил:

    Ну тогда пусть будет с синусами. Можно будет потом с этим кодом фракталы рисовать.

  6. 44
    Альбинка Шакирзянова ответил:

    ну я поэкспериментирую еще)) вдруг какой нить рисунок красивый получится))

  7. 43
    Альбинка Шакирзянова ответил:

    Правильно конечно, но просто мне конкретно с синусами нужно))

  8. 42
    Kitt Wasserfall ответил:

    синус 90=1
    синус -90=-1
    косинус, соответственно, тоже можно заменить на значение переменной, и менять её на 1 или -1 когда надо. Или на 0.

    Это я про данный случай, просто подумал, что можно упростить.

  9. 41
    Альбинка Шакирзянова ответил:

    всмысле? а как иначе? вроде для черепашьей графики всегда нужны, прост здесь угол девыноста градусов

  10. 40
    Kitt Wasserfall ответил:

    Только сейчас понял, что sinи cos там не нужны…

  11. 39
    Альбинка Шакирзянова ответил:

    то есть терь можно сколько угодно закутков делать? Спасибо тебе огромное, ты меня очень выручил!!!!!!!!

  12. 38
    Kitt Wasserfall ответил:

    )))

  13. 37
    Альбинка Шакирзянова ответил:

    посмотри пожалуйста)

  14. 36
    Kitt Wasserfall ответил:

    Вот обновлённыый код, itr – количество ходов (я поставил 14 вместо 10, тестировал), меняя можно получить любую загогулину. Только не ставь нечётное количество. Алсо, перевод в радианы поточнее сделал, теперь линии не пляшут.

    for(int k=0; k<3; k++)
    {
    CD=0;
    angle=90;
    int len;
    dist=len=100;
    int itr;
    itr=14;
    for (int i=0; i<itr; i++)
    {
    if(i<(itr/2-1))
    {
    dist-=len/(itr/2);
    }
    else if(i==itr/2-1)
    {
    angle=-90;
    }
    else if(i>(itr/2)&&i<(itr-1))
    {
    dist+=len/(itr/2);
    }

    x=x+dist*cos(0.017453292519943295769236907684886*CD);
    y=y+dist*sin(0.017453292519943295769236907684886*CD);
    LineTo(hdc,x,y);
    CD-=angle;
    POINT A;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);
    }
    }

  15. 35
    Kitt Wasserfall ответил:

    А, не разглядел. Да, десять ходов. Ща посмотрю.

  16. 34
    Kitt Wasserfall ответил:

    Количество меняется в первом цикле, для отраженного надо поправить алгоритм: x=x-dist*cos(0.017453393*CD);

  17. 33
    Альбинка Шакирзянова ответил:

    ну там же вроде ходов больше получается

  18. 32
    Альбинка Шакирзянова ответил:

    //www.arjuna-design.ru/i/meander.gif а для такого более сложного узора что конкретно меняется?

  19. 31
    Альбинка Шакирзянова ответил:

    ну тоже отраженный должен быть

  20. 30
    Kitt Wasserfall ответил:

    На здоровье ))

  21. 29
    Kitt Wasserfall ответил:

    Как-то так:
    for(int k=0; k<3; k++) //количество повторений
    {
    CD=0;
    angle=90;
    int len;
    dist=len=80;
    for (int i=0; i<8; i++) //ходы
    {
    if(i<3)
    {
    dist-=len/4;
    }
    else if(i==3)
    {
    angle=-90;
    }
    else if(i>4&&i<7)
    {
    dist+=len/4;
    }

    x=x+dist*cos(0.017453393*CD);
    y=y+dist*sin(0.017453393*CD);
    LineTo(hdc,x,y);
    CD-=angle;
    POINT A;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);
    }

    }

  22. 28
    Альбинка Шакирзянова ответил:

    спасибо огромное!!!!!

  23. 27
    Kitt Wasserfall ответил:

    Когда писал, сообщения позже 17:01 не видел.

    А, вот так уже яснее. Общий алгоритм простой вроде как. Если принять длину прямоугольника, в который вписывается один элемент за восемь условных единиц, то высота равняется шести. Черепаха проплзает из исходной точки 6 у/е по горизонтали и поворачивает на 90 градусов против часовой стрелки. Проползает 4 единицы и поворачивает на 90 градусов против часовой стрелки. Проползает 2 ед и снова поворачивает на 90 градусов против часовой стрелки. Снова на 2, но поворачивает против часовой, потом на 2 и снова против часовой, потом на 4 и поворот, потом на шесть, итерации закончены.

    Соответственно, 4 итерации до смены угла, 4 после. Исходные данные – длина и начальная координата.

    Рисовать надо при помощи SetPixel последовательно? Или чкак у тебя черепаха реализовывается?

  24. 26
    Альбинка Шакирзянова ответил:

    как у меня

  25. 25
    Альбинка Шакирзянова ответил:

    это просто последовательно линии рисуются или что? просто мне надо с помощью черепашьей графики

  26. 24
    Альбинка Шакирзянова ответил:

    #include <windows.h>

    //#include "resource.h"

    #include <math.h>

    HINSTANCE hInst;

    char szAppName[] = "ApiWin" ;

    char szTitle[] = "Window Application" ;
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

    int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,

    int nCmdShow)
    {
    MSG msg;
    WNDCLASSEX wc;
    HWND hwnd;
    hInst=hInstance;
    memset(&wc,0, sizeof (wc));
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;

    //wc.hIcon=(HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ICON1),IMAGE_ICON,32,32,0);

    wc.hCursor=LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;
    wc.cbSize= sizeof (WNDCLASSEX);

    //wc.hIconSm=LoadImage(hInst,MAKEINTRESOURCE(IDI_APPICON_SM),IMAGE_ICON,16,16,0);

    if (!RegisterClassEx(&wc))

    return FALSE;
    hwnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
    NULL, NULL, hInst, NULL);

    if (!hwnd)

    return (FALSE);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

    return (msg.wParam);
    }

    int x=600;

    int y=250;

    float CD=0;

    float CD1=-90;

    int dist=100;

    float angle = 90;

    //float angle2 = 60;
    /*void turn(float angle)
    {
    CD+=angle;
    return;
    }
    */

    LRESULT CALLBACK WndProc(
    HWND hwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam)
    {

    static short cxClient, cyClient;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {

    case WM_SIZE:
    {
    cxClient = LOWORD(lParam);
    cyClient = HIWORD(lParam);

    return 0;
    }

    case WM_PAINT:
    {
    hdc=BeginPaint(hwnd,&ps);
    HGDIOBJ hPen=CreatePen(PS_DASH, 5, RGB(0,255,100));
    HGDIOBJ hOldPen=SelectObject(hdc,hPen);
    POINT A;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);

    for ( int j=0; j<1; j++)
    {

    for ( int i=0; i<3; i++)
    {

    const double RadPerDeg=0.017453393;
    x=x+dist*cos(RadPerDeg*CD);
    y=y+dist*sin(RadPerDeg*CD);
    LineTo(hdc,x,y);
    CD=CD+angle;
    POINT A;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);
    }
    MoveToEx(hdc,x,y,lppt);

    const double RadPerDeg=0.017453393;

    //CD=CD-angle;

    x=x+dist*cos(RadPerDeg*CD1);
    y=y+dist*sin(RadPerDeg*CD1);
    LineTo(hdc,x,y);
    POINT A;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);
    }

    EndPaint(hwnd,&ps);

    break ;
    }

    case WM_DESTROY:
    PostQuitMessage(0);

    break ;

    default :

    return (DefWindowProc(hwnd, message, wParam, lParam));
    }

    return (0);
    }

  27. 23
    Альбинка Шакирзянова ответил:

    это я пыталась, но вот только говорю ж сам алгоритм придумать не могу как перо двигаться будет((

  28. 22
    Kitt Wasserfall ответил:

    глобальные переменные
    int ml[9][2]={{0,60},{60,60},{60,20},{40,20},{40,40},{20,40},{20,0},{80,0},{80,60}};
    float moveVar=100;
    int y,x,i,j,w,v,xs,ys,d,d1,d2,dy,dx,sx,sy,ss=0;

    а это в WM_PAINT
    int ixi,ixy;

    for(ixy=0;ixy<10;ixy++){
    for(ixi=0;ixi<8;ixi++){

    xb1=ml[ixi][0]+moveVar+ixy*80;
    yb1=ml[ixi][1]+moveVar;
    xb2=ml[ixi+1][0]+moveVar+ixy*80;
    yb2=ml[ixi+1][1]+moveVar;

    dx=abs(xb2-xb1);
    dy=abs(yb2-yb1);

    sx=xb2>=xb1?1:-1;
    sy=yb2>=yb1?1:-1;

    if(dy<=dx)
    {
    d=(dy<<1)-dx;
    d1=dy<<1;
    d2=(dy-dx)<<1;

    SetPixel (hdc, xb1, yb1, 999999);

    for (x=xb1+sx, y=yb1, i=1; i<=dx; i++, x+=sx)
    {
    if (d>0)
    {
    d+=d2;
    y+=sy;
    }
    else
    d+=d1;
    SetPixel (hdc, x, y, 999999);
    }
    }
    else
    {
    d=(dx<<1)-dx;
    d1=dx<<1;
    d2=(dx-dy)<<1;

    SetPixel (hdc, xb1, yb1, 999999);

    for (x=xb1, y=yb1+sy, i=1; i<=dy; i++, y+=sy)
    {
    if (d>0)
    {
    d+=d2;
    x+=sx;
    }
    else
    d+=d1;
    SetPixel (hdc, x, y, 999999);
    }
    }

    }
    }

  29. 21
    Kitt Wasserfall ответил:

    Я там нарисовал линиями зеркальное отражение этого куска и повторил его несколько раз. На рапиде: //rapidshare.com/files/254927783/m.rar.html

  30. 20
    Альбинка Шакирзянова ответил:

    я открыть не могу( ну судя по описанию то что надо.

  31. 19
    Альбинка Шакирзянова ответил:

    мне тут час ждать очереди
    в общем просто вот этот кусочек орнамента нарисовать надор, а потом размножить еще три раза, и все))

  32. 18
    Kitt Wasserfall ответил:

    Ммм, не особо понял. Вот, глянь: //depositfiles.com/files/ubz0ih05w
    Типа так?

  33. 17
    Альбинка Шакирзянова ответил:

    там просто три таких подряд идет и все

  34. 16
    Kitt Wasserfall ответил:

    Первая ссылка не открывется, а на второй просто кусочек орнамента. Его надо размножить или полноценный вариативный написать?

  35. 15
    Альбинка Шакирзянова ответил:

    ребят, а можете тоже с алгоритмом помочь? мне меандры нужно нарисовать

    //fio.ifmo.ru/archive/group20/c3wu8/pics/meandr...

    //inf.1september.ru/2006/11/26-2.gif
    пожалуйста, очень помощь нужна

  36. 14
    Kitt Wasserfall ответил:

    Вот, мож поможет: //depositfiles.com/files/j574bxizv
    Куб, сделан на матрицах, можно вращать и двигать вершины, нажимая в область около них (не на всех компах работает почему-то).
    На первом курсе писалась, поэтому там всё навалом в WM_PAINT лежит, а не отдельными функциями.

  37. 13
    Cyber Max ответил:

    Никто не обещал что будет легко :) хотя на самом деле ничего сложного нет. Только внимательно читать MSDN и вникать в каждую строчку кода… она ведь не для красоты там написана – значит для чего то нужна! и проблемм не будет :)

  38. 12
    Павел Федулов ответил:

    WinAPI – это горе для неё, я это имел ввиду)))))))

  39. 11
    Cyber Max ответил:

    WinAPI – это не горе.. аразминка для ума + хорошее понимание того, что вы делаете на самом деле… Не говорю что все нужно писать на WinAPI (особенно графику). Для системных целей это просто незаминимый инструмент, уметь работать с которым хорошему программисту просто необходимо!

  40. 10
    Павел Федулов ответил:

    WinAPI это горе, но если надо- пиши в личку пришлю готову прогу

  41. 9
    Артур Терменжи ответил:

    какая в поряде девушка учит винапи..)

  42. 8
    Михаил Митрофанов ответил:

    вот это и есть эксепшн, т.е. ошибка исполнения.
    Для определения таких ошибок – используйте дебаггер, т.е. становитесь на строку, где, предположительно, ошибка, нажимаете F9(Breakpoint, делее F5(Start debuggin). И пошагово начинаете отлаживать программу.

  43. 7
    Larina Salivan ответил:

    а exception, простите, что это? не поняла)

  44. 6
    Larina Salivan ответил:

    программа запускается с 4-мя warningами, появляется поле, где должен быть нарисован шестиугольник, но сразу выскакивает окошко с debug error :(

  45. 5
    Larina Salivan ответил:

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

  46. 4
    Михаил Митрофанов ответил:

    int x=50;
    int y=50;
    float CD=0;
    int dist=20;

    float angle = 30;void forward(int dist)
    {
    const float RadPerDeg=0.01745339;

    //Ну во первых есть exception.
    //Сударыня, не создавайте глобальных переменных
    //потому что в следующих двух строчках Вы переопределяете х и у
    //и они становятся неинициализированными

    int x=x+dist*cos(RadPerDeg*CD);
    int y=y+dist*sin(RadPerDeg*CD);

    //Создан объект HDC – но тоже непроинициализирован

    HDC hdc;
    LineTo(hdc,x,y);

    POINT A;
    A.x=100;
    A.y=100;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);
    return;
    }

  47. 3
    Михайло Володимирович ответил:

    angle должен быть 60

  48. 2
    Тоша Мартынов ответил:

    я бы сделал
    void forward(HDC hdc, int dist)
    {
    const float RadPerDeg=0.01745339;
    int x=x+dist*cos(RadPerDeg*CD);
    int y=y+dist*sin(RadPerDeg*CD);
    LineTo(hdc,x,y);

    POINT A;
    A.x=100;
    A.y=100;
    POINT FAR* lppt=&A;
    MoveToEx(hdc,x,y,lppt);
    return;
    }

    потом…
    какой смысл в
    void turnTo(float angle)
    {
    angle=CD;
    return;
    }
    Первое, что Вы делаете – это обнуляете переменную angle, а затем
    void turn(float angle)
    {
    CD+=angle;
    return;
    }
    к нулю добавляете ноль…
    бррррррр……

    А не легче было бы составить массив POINT [6], вычислить вершины шестиугольника и нарисовать его функцией, например, PolylineTo()

  49. 1
    Larina Salivan ответил:

    dist- это длины шестиугольника, CD-начальное значение угла, angle – шаг, на который будет изменяться угол, x,y=50- начальные значения координат пера)

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.