vẽ bông hoa

Xem chủ đề cũ hơn Xem chủ đề mới hơn Go down

vẽ bông hoa

Bài gửi by nth on 03/04/10, 08:04 pm

// ve bong hoa 0404.cpp : Defines the entry point for the application.
// nth
// 04042010

#include "stdafx.h"
#include "resource.h"
#include <math.h>

#define MAX_LOADSTRING 100
#define MAX_MARKERS 100
#define MARKER_SIZE 5

// khai bao struct Bong Hoa
struct BongHoa{
POINT Tam;
POINT DiemDieuKhien;
COLORREF MauVien;
COLORREF MauTo;
};

// khai bao ham
void DrawMarker(HDC hdc, POINT pt, int size);
void DrawFlower(HDC hdc, BongHoa phoa, int SoCanh, int GocNghieng);
POINT QuayDiem (POINT Tam, POINT p, int GocQuay);

// ===========================
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

// khai bao cac bien se dung
int i;
static int GocNghieng = 0, SoCanh = 4;
static POINT apt[MAX_MARKERS];
static int nMarkers = 0;

static BongHoa bonghoa[100];
static int nbonghoa = 0;

switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);

switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd,
(DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
                default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CHAR:
switch(wParam)
{
// thay doi mau hoa
case 'c':
for(i = 0; i<nbonghoa; i++)
{
bonghoa[i].MauTo = RGB(rand()%255,
rand()%255, rand()%255);
bonghoa[i].MauVien = RGB(rand()%255,
rand()%255, rand()%255);
}
InvalidateRect(hWnd, NULL, TRUE);
break;
// tang kich thuoc hoa
case 't':
for ( i= 0; i < nbonghoa; i++)
{
bonghoa[i].DiemDieuKhien.x++;
bonghoa[i].DiemDieuKhien.y++;
}
InvalidateRect(hWnd,NULL,TRUE);
break;
// giam kich thuoc hoa
case 'g':
for ( i= 0; i < nbonghoa; i++)
{
bonghoa[i].DiemDieuKhien.x--;
bonghoa[i].DiemDieuKhien.y--;
}
InvalidateRect(hWnd,NULL,TRUE);
break;
// di chuyen cheo xuong
case 'm':
for(i = 0; i < nbonghoa; i++)
{
bonghoa[i].Tam.x++;
bonghoa[i].Tam.y++;
bonghoa[i].DiemDieuKhien.x++;
bonghoa[i].DiemDieuKhien.y++;

}
InvalidateRect(hWnd, NULL, TRUE);
break;
// di chuyen cheo len
case 'y':
for(i = 0; i < nbonghoa; i++)
{
bonghoa[i].Tam.x--;
bonghoa[i].Tam.y--;
bonghoa[i].DiemDieuKhien.x--;
bonghoa[i].DiemDieuKhien.y--;
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case 'u':
for(i = 0; i < nbonghoa; i++)
{
bonghoa[i].Tam.y--;
bonghoa[i].DiemDieuKhien.y--;
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case 'n':
for(i = 0; i < nbonghoa; i++)
{
bonghoa[i].Tam.y++;
bonghoa[i].DiemDieuKhien.y++;
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case 'j':
for(i = 0; i < nbonghoa; i++)
{
bonghoa[i].Tam.x++;
bonghoa[i].DiemDieuKhien.x++;
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case 'h':
for(i = 0; i < nbonghoa; i++)
{
bonghoa[i].Tam.x--;
bonghoa[i].DiemDieuKhien.x--;
}
InvalidateRect(hWnd, NULL, TRUE);
break;

}
break;

case WM_RBUTTONDOWN:
nMarkers = 0;
InvalidateRect(hWnd, NULL, TRUE);
break;

case WM_LBUTTONDOWN:
if(nMarkers <= MAX_MARKERS)
{
apt[nMarkers].x = LOWORD(lParam);
apt[nMarkers].y = HIWORD(lParam);

// khi nhap chuot diem thu hai se xac dinh tam
// va diem dieu khien cua bong hoa
if((nMarkers+1)%2 == 0)
{
bonghoa[nbonghoa].Tam = apt[nMarkers - 1];
bonghoa[nbonghoa].DiemDieuKhien = apt[nMarkers];
bonghoa[nbonghoa].MauTo = RGB(rand()%255,
rand()%255, rand()%255);
bonghoa[nbonghoa].MauVien = RGB(rand()%255,
rand()%255, rand()%255);
nbonghoa++;

}
nMarkers++;
InvalidateRect(hWnd, NULL, TRUE);
}
break;

case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
if(SoCanh > 3) SoCanh = SoCanh - 1;
break;
case VK_RIGHT:
if(SoCanh < 15) SoCanh = SoCanh + 1;
break;
case VK_UP:
GocNghieng += 10;
break;
case VK_DOWN:
GocNghieng -= 10;
break;
}
InvalidateRect(hWnd, NULL, TRUE);
break;

case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);

// Ve cac dau Marker
for (i = 0; i < nMarkers; i++)
{
DrawMarker(hdc, apt[i], MARKER_SIZE);
}

// ve bong hoa
for(i = 0; i< nbonghoa; i++)
DrawFlower(hdc, bonghoa[i], SoCanh, GocNghieng);

EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
        default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

// Ham ve dau markers
void DrawMarker(HDC hdc, POINT pt, int size)
{
int i;
for (i = 1; i <= size; i++)
{
SetPixel(hdc, pt.x-i, pt.y, RGB(0,0,0));
SetPixel(hdc, pt.x+i, pt.y, RGB(0,0,0));
SetPixel(hdc, pt.x, pt.y-i, RGB(0,0,0));
SetPixel(hdc, pt.x, pt.y+i, RGB(0,0,0));
}
}

// Ham ve bong hoa
void DrawFlower(HDC hdc, BongHoa phoa, int SoCanh, int GocNghieng)
{
HBRUSH hbr; HPEN hpen;
hpen = CreatePen(PS_SOLID, 3, phoa.MauVien);
hbr = CreateSolidBrush(phoa.MauTo);
SelectObject(hdc, hbr);
SelectObject(hdc, hpen);

// dung de mo mien va dong mien can to
BeginPath(hdc);

double PI = 3.1415926;
POINT *aptFlower;
aptFlower = new POINT[3*SoCanh];
// tinh 3 diem cho 1 canh hoa nam o giua diem aptFlower[0] va
// aptFlower[1]
aptFlower[0] = phoa.DiemDieuKhien;
// xac dinh truoc 3 diem de ve 1 canh hoa
aptFlower[1].x = 2 * phoa.Tam.x - aptFlower[0].x;
aptFlower[1].y = aptFlower[0].y;
aptFlower[2] = phoa.Tam;

// { xoay canh hoa nay theo so goc chia
int GocChia = 360 / SoCanh;
int j = 1;
// {tuy theo so canh hoa se tien hanh quay tao ra cac canh khac
for (int i = 3; i < 3*SoCanh; i = i + 3, j++)
{
aptFlower[i] = QuayDiem(phoa.Tam, aptFlower[0], j*GocChia);
aptFlower[i+1] = QuayDiem(phoa.Tam, aptFlower[1], j*GocChia);
aptFlower[i+2] = QuayDiem(phoa.Tam, aptFlower[2], j*GocChia);
}

// Quay bong hoa
for ( i=0; i < 3*SoCanh; i++)
aptFlower[i] = QuayDiem(phoa.Tam, aptFlower[i], GocNghieng);

// bat dau ve bong hoa
MoveToEx(hdc, phoa.Tam.x, phoa.Tam.y, NULL);
// dung PolyBezierTo de ve bong hoa
PolyBezierTo(hdc, aptFlower, 3*SoCanh);
// kiem tra xem co dung la duong kin khong
CloseFigure(hdc);
EndPath(hdc);
// kiem tra da xong, bat dau to
StrokeAndFillPath(hdc);

DeleteObject(hbr);
DeleteObject(hpen);
}

// Ham Quay 1 diem p quay quanh tam mot goc xac dinh.
// (Ham dung cong thuc toan hoc)
POINT QuayDiem (POINT Tam, POINT p, int GocQuay)
{
double PI = 3.1415926;
POINT kq;
double r = sqrt(pow(p.x - Tam.x, 2) + pow(p.y - Tam.y, 2));
double goc = acos((double)(p.x - Tam.x)/r);

goc = (p.y <= Tam.y) ? 2 * PI - goc : goc;
goc = goc + ((GocQuay * PI) / 180);

kq.x = Tam.x + (long)(r*cos(goc));
kq.y = Tam.y + (long)(r*sin(goc));
return kq;
}


Được sửa bởi nth ngày 06/05/10, 05:24 pm; sửa lần 3.

===== Thành viên Forum Thien Than CNTT ====
Nothing!

(~~/)
(~'.'~)
(_(__)~~

nth
Admin
Admin

Tổng số bài gửi: 550
Số điểm: 1113
Số lần được cám ơn: 33
Ngày đến diễn đàn:: 01/08/2009
Tuổi: 26
Đến từ: Thiên Đường

Xem lý lịch thành viên http://thuhuong.hot4um.com

Về Đầu Trang Go down

Re: vẽ bông hoa

Bài gửi by nth on 03/04/10, 08:14 pm

file đính kèm: ve bong hoa
tài liệu liên quan: file pdf

===== Thành viên Forum Thien Than CNTT ====
Nothing!

(~~/)
(~'.'~)
(_(__)~~

nth
Admin
Admin

Tổng số bài gửi: 550
Số điểm: 1113
Số lần được cám ơn: 33
Ngày đến diễn đàn:: 01/08/2009
Tuổi: 26
Đến từ: Thiên Đường

Xem lý lịch thành viên http://thuhuong.hot4um.com

Về Đầu Trang Go down

Re: vẽ bông hoa

Bài gửi by nth on 03/04/10, 08:19 pm

Có 1 điều mà mình hơi thắc mắc ( cũng là ý kiến của bạn K), trong hàm vẽ bông hoa:
for (int i = 3; i < 3*SoCanh; i = i + 3, j++)
{
aptFlower[i] = QuayDiem(phoa.Tam, aptFlower[0], j*GocChia);
aptFlower[i+1] = QuayDiem(phoa.Tam, aptFlower[1], j*GocChia);
aptFlower[i+2] = QuayDiem(phoa.Tam, aptFlower[2], j*GocChia);
}

mình nghĩ là
aptFlower[i+2] = QuayDiem(phoa.Tam, aptFlower[2], j*GocChia);
lưu tâm, mà mỗi cánh hoa đều có chung một tâm. Vậy có cần cái dòng này không? Mình chưa test thử với bài của mình, tại đang bận làm CCLTM mai nộp rồi, có lẽ ngày mốt mình mới thử. Nhưng mình thấy cái đó cũng khá hợp lý. Các bạn có ý kiến gì không? chỉ mình với..

===== Thành viên Forum Thien Than CNTT ====
Nothing!

(~~/)
(~'.'~)
(_(__)~~

nth
Admin
Admin

Tổng số bài gửi: 550
Số điểm: 1113
Số lần được cám ơn: 33
Ngày đến diễn đàn:: 01/08/2009
Tuổi: 26
Đến từ: Thiên Đường

Xem lý lịch thành viên http://thuhuong.hot4um.com

Về Đầu Trang Go down

Re: vẽ bông hoa

Bài gửi by nth on 06/04/10, 09:32 am

hôm nay mới rảnh xem lại vấn đề này.
@K: theo mình nghĩ thì khi mình dùng PolyBezier để vẽ, nó dùng 1 mảng để lưu các điểm, và nó duyệt cái mảng đó từ đầu. Mỗi lần vẽ là túm 3 em theo đúng thứ tự để vẽ. Do vậy, cho dù là giá trị của các phần tử ở vị trí a[2] = a[5]=.. nhưng mà nó vẫn phải lưu. Vì nó có biết tại giá trị đó là tâm đâu. Nó chỉ hiểu theo cách duyệt phần tử thông thường thôi.

===== Thành viên Forum Thien Than CNTT ====
Nothing!

(~~/)
(~'.'~)
(_(__)~~

nth
Admin
Admin

Tổng số bài gửi: 550
Số điểm: 1113
Số lần được cám ơn: 33
Ngày đến diễn đàn:: 01/08/2009
Tuổi: 26
Đến từ: Thiên Đường

Xem lý lịch thành viên http://thuhuong.hot4um.com

Về Đầu Trang Go down

Xem chủ đề cũ hơn Xem chủ đề mới hơn Về Đầu Trang


Permissions in this forum:
Bạn không có quyền trả lời bài viết