программа должна рисовать кривую Коха
#include <windows.h>
#include <math.h>
//#include "resource.h"
HINSTANCE hInst;
char szAppName[] ="ApiWin";
char szTitle[] ="Window Application";
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Koch(float startx, float endx, float starty, float endy, int level);
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);
}
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
{
hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,10,20,"Message WM_PAINT",16);
Koch(100,800,400,400,7);
EndPaint(hwnd,&ps);
break;
}
case WM_LBUTTONDOWN:
MessageBox(NULL,"Hello, 32-bit world!","Window",MB_OK);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hwnd, message, wParam, lParam));
}
return (0);
}
void Koch(float startx, float endx, float starty, float endy, int level){
if(level==1){
line(startx, starty, endx, endy);
}
L = sqrt( (endx-startx) * (endx-startx) + (endy-starty) * (endy-starty) );
h = L /(2 * sqrt(3));
sina = (endy – starty)/L;
cosa = (endx – startx)/L;
x1 = startx + (endx – startx)/3;
x2 = (endx + startx)/2 + h * sina;
x3 = startx + 2 * (endx – startx)/3;
y1 = starty + (endy – starty)/3;
y2 = (endy + starty)/2 – h * cosa;
y3 = starty + 2 * (endy – starty)/3;
Koch(startx, x1, starty, y1, level-1);
Koch(x1, x2, y1, y2, level-1);
Koch(x2, x3, y2, y3, level-1);
Koch(x3, endx, y3, endy, level-1);}
9 июля 2009 в 22:00
Тип можно не менять… Но решение с ветвлением тоже верно, просто свое предложил недочитав до него – не заметил, что есть вторая страница
9 июля 2009 в 0:04
ну как вариант можно но только возвращаемый тип void придется поменять, хотя я лично в этом смысла особого не вижу, с ветвлением и так не будет никаких проблем тут, как например переполнение стека ИМХО )
Хотя с таким решеним проблемы полностью согласен )
9 июля 2009 в 0:02
Предлагаю в качестве выхода из рекурсии использовать кусок
if(level==1)
{
DrawLine(hdc, startx, starty, endx, endy);
}
Добавив в него банальный return:
if(level==1)
{
DrawLine(hdc, startx, starty, endx, endy);
return;
}
9 июля 2009 в 0:01
ээээ давай-ка по-подробней… выложи код и что за платформа?
8 июля 2009 в 19:04
Не подскажете, почему программа выдает "sigmentation fallout" если в ней присутствует массив char?
8 июля 2009 в 12:04
условия для корректного выхода из рекурсии:
void Koch(float startx, float endx, float starty, float endy, int level, HDC hdc)
{
float L = 0, sina = 0, cosa = 0, h = 0, x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, y3 = 0;
if(level==1)
{
DrawLine(hdc, startx, starty, endx, endy);
}
else
{
L = (float)sqrt( (endx-startx) * (endx-startx) + (endy-starty) * (endy-starty) );
h = (float)L /(2 * sqrt(3));
sina = (endy – starty)/L;
cosa = (endx – startx)/L;
x1 = startx + (endx – startx)/3;
x2 = (endx + startx)/2 + h * sina;
x3 = startx + 2 * (endx – startx)/3;
y1 = starty + (endy – starty)/3;
y2 = (endy + starty)/2 – h * cosa;
y3 = starty + 2 * (endy – starty)/3;
Koch(startx, x1, starty, y1, level-1,hdc);
Koch(x1, x2, y1, y2, level-1,hdc);
Koch(x2, x3, y2, y3, level-1,hdc);
Koch(x3, endx, y3, endy, level-1,hdc);
}
};
8 июля 2009 в 11:04
ну чтобы ошибки снять попробуй убрать мои float ы и поставить int посмотрим что из этого получится…
про переполнение, да будет переполняться везде, т.к. не был продуман выход из рекурсивного вызова функции, а вот как это исправить я еще думаю, никогда рекурсию не любил (
8 июля 2009 в 11:04
у меня за год учебы ни одной лабы не было на рекурсию)) поэтому я тоже не очень. ну если придумаете, то будет отлично)
8 июля 2009 в 11:04
ооооо я думал это тока у нас в универе мы лабы лабами называем )))))) сейчас что-нибудь придумаем…
8 июля 2009 в 11:04
))))
8 июля 2009 в 11:03
у меня visual studio 2008, отсюда и проблемы с переносимостью, но это не беда… рисовать оно не рисует, т.к. просто не успевает видимо стек переполняется выводится ошибка и виснет
8 июля 2009 в 11:03
и что сделать с этим?)) а в моих версиях тож должен переполняться?
8 июля 2009 в 11:02
да есть. не может перевести float в int
MoveToEx(hdc, x1, y1, &pt);
return LineTo(hdc, x2, y2);
и насчет sqrt пишет ambiguous call to overloaded function в строке
h = (float)L /(2 * sqrt(3));
8 июля 2009 в 11:02
хм странно, что у тебя за платформа? у меня собралась нормально…
8 июля 2009 в 11:02
visual studio 2005.ну у меня еще есть просто с++ 6я версия. а у вас какая? рисует нормально?
8 июля 2009 в 11:01
ну ошибок нет, программа запускается, но переполнение стека идет ((( чтобы это убрать надо еще глянуть… А что? есть еще ошибки?
8 июля 2009 в 11:00
Да и еще ты забыла про #include "stdafx.h"
8 июля 2009 в 11:00
Теекс вобщем чтобы код просто заработал достаточно сделать вот так. В кратце у тебя нету функции line, которая рисует прямую по двум точкам есть аналог – LineTo, она рисует прямую от текущей позиции до заданной. я написал свою функцию DrawLine, которая рисует прямую по 2м точкам:
#include "stdafx.h"
#include <windows.h>
#include <math.h>
//#include "resource.h"
HINSTANCE hInst;
char szAppName[] ="ApiWin";
char szTitle[] ="Window Application";
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Koch(float startx, float endx, float starty, float endy, int level, HDC hdc);
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);
};
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
{
hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,10,20,"Message WM_PAINT",16);
Koch(100,800,400,400,7,hdc);
EndPaint(hwnd,&ps);
break;
}
case WM_LBUTTONDOWN:
MessageBox(NULL,"Hello, 32-bit world!","Window",MB_OK);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hwnd, message, wParam, lParam));
}
return (0);
};
BOOL DrawLine(HDC hdc, float x1, float y1, float x2, float y2)
{
POINT pt;
MoveToEx(hdc, x1, y1, &pt);
return LineTo(hdc, x2, y2);
};
void Koch(float startx, float endx, float starty, float endy, int level, HDC hdc)
{
static float L = 0, sina = 0, cosa = 0, h = 0, x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, y3 = 0;
if(level==1)
{
DrawLine(hdc, startx, starty, endx, endy);
}
L = (float)sqrt( (endx-startx) * (endx-startx) + (endy-starty) * (endy-starty) );
h = (float)L /(2 * sqrt(3));
sina = (endy – starty)/L;
cosa = (endx – startx)/L;
x1 = startx + (endx – startx)/3;
x2 = (endx + startx)/2 + h * sina;
x3 = startx + 2 * (endx – startx)/3;
y1 = starty + (endy – starty)/3;
y2 = (endy + starty)/2 – h * cosa;
y3 = starty + 2 * (endy – starty)/3;
Koch(startx, x1, starty, y1, level-1,hdc);
Koch(x1, x2, y1, y2, level-1,hdc);
Koch(x2, x3, y2, y3, level-1,hdc);
Koch(x3, endx, y3, endy, level-1,hdc);
};
8 июля 2009 в 11:00
ммдээ.. получается если использовать LineTo то надо переделывать всю функцию
8 июля 2009 в 11:00
Но основная проблема даже не в этом!!! Ты для построения кривой используешь рекурсию, с ней надо быть очень осторожным, если не продумать условия выхода получишь переполнение стека, что собственно у тебя и происходит…
8 июля 2009 в 11:00
оо спасибо)) сейчас проверю))
8 июля 2009 в 11:00
а у вас работает, та которую вы мне прислали?
8 июля 2009 в 10:05
не пробовала. по идее, без функции коха все нормально. но когда я вставляю функцию то ничего не работает. то есть я либо не так ее вставляю либо еще что-то
8 июля 2009 в 10:05
там проблема в том, что функции line нету, используй что-то другое для рисования линии например LineTo
8 июля 2009 в 10:04
А вы не пробовали пошагово пройтись дебагером по программе или закомментировать куски кода по частям в поисках неправильно работающего и попытаться найти неправильно работающий участок кода?