Главная страница
Навигация по странице:

  • Институт информационных технологий Кафедра Инженерной графики

  • ЛР. ИДБ-20-08_Вихров_ЛР5_Отчет. Отчет по дисциплине Компьютерная геометрия и графика по лабораторной работе 5


    Скачать 285.57 Kb.
    НазваниеОтчет по дисциплине Компьютерная геометрия и графика по лабораторной работе 5
    Дата07.12.2022
    Размер285.57 Kb.
    Формат файлаdocx
    Имя файлаИДБ-20-08_Вихров_ЛР5_Отчет.docx
    ТипОтчет
    #832671



    МИНОБРНАУКИ РОССИИ

    федеральное государственное бюджетное образовательное учреждение

    высшего образования

    «Московский государственный технологический университет «СТАНКИН»

    (ФГБОУ ВО «МГТУ «СТАНКИН»)


    Институт
    информационных технологий

    Кафедра

    Инженерной графики


    Основная образовательная программа 09.03.02
    «Информационные системы и технологии»


    Отчет по дисциплине «Компьютерная геометрия и графика»

    по лабораторной работе № 5



    Студент

    группы ИДБ-20-08

    Вихров Кирилл Александрович







    Преподаватель

    Разумовский А.И.

    Москва, 2021 г.

    ОГЛАВЛЕНИЕ




    ВВЕДЕНИЕ


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

    ОСНОВНАЯ РАБОТА

    Код “Вращающийся куб”.


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

    {

    switch (message)

    {

    case WM_COMMAND:

    {

    int wmId = LOWORD(wParam);

    // Parse the menu selections:

    switch (wmId)

    {

    case IDM_ABOUT:

    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

    break;

    case IDM_EXIT:

    DestroyWindow(hWnd);

    break;

    default:

    return DefWindowProc(hWnd, message, wParam, lParam);

    }

    }

    break;

    POINT point1[4];

    HDC hdc;

    int sx, sy, xPos, yPos, zDelta;

    case WM_MOUSEMOVE:

    sx = LOWORD(lParam); //координата мыши по оси Х

    sy = HIWORD(lParam); //координата мыши по оси У

    thetta += ((sx % 180) - 90) / 10;

    phi += ((sy % 180) - 90) / 10;

    InvalidateRect(hWnd, NULL, TRUE);

    break;

    case WM_MOUSEWHEEL:

    zDelta = (int)wParam; // wheel rotation

    ScreenDist -= zDelta / 1000000.;

    InvalidateRect(hWnd, NULL, TRUE);

    break;

    case WM_PAINT:

    {

    hdc = BeginPaint(hWnd, &ps);

    th = thetta * factor; ph = phi * factor;

    costh = cos(th); sinth = sin(th); cosph = cos(ph); sinph = sin(ph);

    A = rho * sinph * costh; B = rho * sinph * sinth; C = rho * cosph;

    Al = A / (sqrt(A * A + B * B + C * C));

    Bl = B / (sqrt(A * A + B * B + C * C));

    Cl = C / (sqrt(A * A + B * B + C * C));

    for (int i = 0; i < 6; i++)

    {

    for (int j = 0; j < 3; j++)

    {

    xt[j] = CubePoints[Gran[i][j]].X;

    yt[j] = CubePoints[Gran[i][j]].Y;

    zt[j] = CubePoints[Gran[i][j]].Z;

    }

    //

    A = yt[0] * (zt[1] - zt[2]) - yt[1] * (zt[0] - zt[2]) + yt[2] * (zt[0] - zt[1]);

    B = -(xt[0] * (zt[1] - zt[2]) - xt[1] * (zt[0] - zt[2]) + xt[2] * (zt[0] - zt[1]));

    C = xt[0] * (yt[1] - yt[2]) - xt[1] * (yt[0] - yt[2]) + xt[2] * (yt[0] - yt[1]);

    An = A / (sqrt(A * A + B * B + C * C));

    Bn = B / (sqrt(A * A + B * B + C * C));

    Cn = C / (sqrt(A * A + B * B + C * C));

    //

    alpha = (An * Al + Bn * Bl + Cn * Cl);

    //

    for (int j = 0; j < 4; j++)

    {

    point1[j] = Perspective(CubePoints[Gran[i][j]].X,

    CubePoints[Gran[i][j]].Y,

    CubePoints[Gran[i][j]].Z);

    }

    // Определение направления обхода точек грани для выявления ориентации к

    // наблюдателю

    D = point1[0].x * (point1[1].y - point1[2].y) -

    point1[1].x * (point1[0].y - point1[2].y) +

    point1[2].x * (point1[0].y - point1[1].y);

    if (D < 0)

    {

    hBrush = CreateSolidBrush(RGB((1 - alpha) * 255,

    (1 - alpha) * 255, (1 - alpha) * 255));

    SelectObject(hdc, hBrush);

    Polygon(hdc, point1, 4);

    }

    }

    EndPaint(hWnd, &ps);

    break;

    }

    case WM_DESTROY:

    PostQuitMessage(0);

    break;

    default:

    return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

    }

    Результат работы программы отображается на рисунке 1:



    Рис.1 “Вращающийся куб”

    Код “Кривая Безье”


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

    {

    static HPEN hDash, hBezier; // два пера

    static HBRUSH hRect, hSel; // две кисти

    static POINT pt[20]; // массив хранения плоских точек

    static POINT point; // структура под одну плоскую точку

    RECT rt; // структура точек прямоугольника

    static int count = 0, index = 0; // счётчик точек,

    static bool capture = 0; // логическая переменная для мыши

    int i;

    HDC hdc;

    PAINTSTRUCT ps;

    ifstream in; //класс файлового потокового ввода-вывода

    ofstream out;

    switch (message)

    {

    case WM_COMMAND:

    {

    int wmId = LOWORD(wParam);

    // Parse the menu selections:

    switch (wmId)

    {

    case IDM_ABOUT:

    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

    break;

    case IDM_EXIT:

    DestroyWindow(hWnd);

    break;

    default:

    return DefWindowProc(hWnd, message, wParam, lParam);

    }

    }

    break;

    case WM_CREATE:

    in.open("dat.txt"); // открытие файлового потока

    if (in.fail())

    {

    MessageBox(hWnd, _T("Файл dat.txt не найден"),

    _T("Открытие файла"), MB_OK | MB_ICONEXCLAMATION);

    PostQuitMessage(0);

    return 1;

    }

    // пока запоняется координата x - заполняем y

    // в переменной count накапливается размер массива точек

    for (count = 0; in >> pt[count].x; count++) in >> pt[count].y;

    in.close(); // закрытие файлового потока

    hDash = CreatePen(PS_DASH, 1, 0);

    hBezier = CreatePen(PS_SOLID, 4, RGB(0, 0, 255));

    hRect = CreateSolidBrush(RGB(128, 0, 128));

    hSel = CreateSolidBrush(RGB(255, 0, 0));

    break;

    case WM_SIZE:

    sx = LOWORD(lParam);

    sy = HIWORD(lParam);

    break;

    case WM_LBUTTONDOWN:

    point.x = LOWORD(lParam);

    point.y = HIWORD(lParam);

    //Преобразование экранных координат мыши в логические

    DcInLp(point);

    for (i = 0; i <= count; i++)

    {

    SetRect(&rt, pt[i].x - MARK, pt[i].y - MARK,

    pt[i].x + MARK, pt[i].y + MARK);

    if (PtInRect(&rt, point))

    { // Курсор мыши попал в точку

    index = i;

    capture = true;

    hdc = GetDC(hWnd);

    transform(hdc); //Переход в логические координаты

    FillRect(hdc, &rt, hSel);//Отметим прямоугольник цветом

    ReleaseDC(hWnd, hdc);

    SetCapture(hWnd);

    return 0;

    }

    }

    break;

    case WM_LBUTTONUP:

    if (capture)

    {

    ReleaseCapture(); //Освобождение мыши

    capture = false;

    }

    break;

    case WM_MOUSEMOVE:

    if (capture)

    { //Мышь захвачена

    point.x = LOWORD(lParam);

    point.y = HIWORD(lParam);

    DcInLp(point); //Преобразование экранных координат мыши

    pt[index] = point; // в логические координаты

    InvalidateRect(hWnd, NULL, TRUE);

    }

    break;

    case WM_PAINT:

    hdc = BeginPaint(hWnd, &ps);

    transform(hdc); //Переход в логические координаты

    SelectObject(hdc, hDash);

    Polyline(hdc, pt, count); //Строим ломанную линию

    SelectObject(hdc, hBezier);

    PolyBezier(hdc, pt, count); //Строим кривую Безье

    for (i = 0; i < count; i++)

    { //Закрашиваем точки графика прямоугольниками

    SetRect(&rt, pt[i].x - MARK, pt[i].y - MARK,

    pt[i].x + MARK, pt[i].y + MARK);

    FillRect(hdc, &rt, hRect);

    }

    break;

    case WM_DESTROY:

    DeleteObject(hDash);

    DeleteObject(hBezier);

    DeleteObject(hRect);

    DeleteObject(hSel);

    out.open("dat.txt"); //открыть файловый поток для записи даннах

    for (i = 0; i < count; i++) out << pt[i].x << '\t' << pt[i].y << '\n';

    out.close();

    default:

    return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

    }

    Результат работы программы отображается на рисунке 2:



    Рис 2. “Кривая Безье”

    Код “Кривая Безье(функция)”


    void PolySplayn(HDC hdc, POINT pt[], int count)

    {

    float a0, a1, a2, a3, b0, b1, b2, b3, t,first = -1;

    int X, Y, eps = 20;

    for (int i = -1; i <= count-1 ; i++) {

    MoveToEx(hdc, pt[i].x - eps, pt[i].y - eps, NULL);

    LineTo(hdc, pt[i].x + eps, pt[i].y + eps);

    MoveToEx(hdc, pt[i].x - eps, pt[i].y + eps, NULL);

    LineTo(hdc, pt[i].x + eps, pt[i].y - eps);


    }

    for (int i = 1; i <= count-2 ; i++)

    {

    a3 = (-pt[i - 1].x + 3 * (pt[i].x - pt[i + 1].x) + pt[i + 2].x) / 6;

    b3 = (-pt[i - 1].y + 3 * (pt[i].y - pt[i + 1].y) + pt[i + 2].y) / 6;

    a2 = (pt[i - 1].x - 2 * pt[i].x + pt[i + 1].x) / 2;

    b2 = (pt[i - 1].y - 2 * pt[i].y + pt[i + 1].y) / 2;

    a1 = (pt[i + 1].x - pt[i - 1].x) / 2;

    b1 = (pt[i + 1].y - pt[i - 1].y) / 2;

    a0 = (pt[i - 1].x + 4 * pt[i].x + pt[i + 1].x) / 6;

    b0 = (pt[i - 1].y + 4 * pt[i].y + pt[i + 1].y) / 6;
    for (int j = 0; j <= 30; j++)

    {

    t = (float)j / 30;

    X = ((a3 * t + a2) * t + a1) * t + a0;

    Y = ((b3 * t + b2) * t + b1) * t + b0;

    if (first)

    {

    first = 0; MoveToEx(hdc, X, Y, NULL);

    }

    else LineTo(hdc, X, Y);

    }

    }

    }
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

    {

    static HPEN hDash, hBezier; // два пера

    static HBRUSH hRect, hSel; // две кисти

    static POINT pt[20]; // массив хранения плоских точек

    static POINT point; // структура под одну плоскую точку

    RECT rt; // структура точек прямоугольника

    static int count = 0, index = 0; // счётчик точек,

    static bool capture = 0; // логическая переменная для мыши

    int i;

    HDC hdc;

    PAINTSTRUCT ps;

    ifstream in; //класс файлового потокового ввода-вывода

    ofstream out;
    switch (message)

    {

    case WM_COMMAND:

    {

    int wmId = LOWORD(wParam);

    // Parse the menu selections:

    switch (wmId)

    {

    case IDM_ABOUT:

    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

    break;

    case IDM_EXIT:

    DestroyWindow(hWnd);

    break;

    default:

    return DefWindowProc(hWnd, message, wParam, lParam);

    }

    }

    break;

    case WM_CREATE:

    in.open("dat.txt"); // открытие файлового потока

    if (in.fail())

    {

    MessageBox(hWnd, _T("Файл dat.txt не найден"),

    _T("Открытие файла"), MB_OK | MB_ICONEXCLAMATION);

    PostQuitMessage(0);

    return 1;

    }

    // пока запоняется координата x - заполняем y

    // в переменной count накапливается размер массива точек

    for (count = 0; in >> pt[count].x; count++) in >> pt[count].y;

    in.close(); // закрытие файлового потока

    hDash = CreatePen(PS_DASH, 1, 0);

    hBezier = CreatePen(PS_SOLID, 4, RGB(0, 0, 255));

    hRect = CreateSolidBrush(RGB(128, 0, 128));

    hSel = CreateSolidBrush(RGB(255, 0, 0));

    break;

    case WM_SIZE:

    sx = LOWORD(lParam);

    sy = HIWORD(lParam);

    break;

    case WM_LBUTTONDOWN:

    point.x = LOWORD(lParam);

    point.y = HIWORD(lParam);

    //Преобразование экранных координат мыши в логические

    DcInLp(point);

    for (i = 0; i <= count; i++)

    {

    SetRect(&rt, pt[i].x - MARK, pt[i].y - MARK,

    pt[i].x + MARK, pt[i].y + MARK);

    if (PtInRect(&rt, point))

    { // Курсор мыши попал в точку

    index = i;

    capture = true;

    hdc = GetDC(hWnd);

    transform(hdc); //Переход в логические координаты

    FillRect(hdc, &rt, hSel);//Отметим прямоугольник цветом

    ReleaseDC(hWnd, hdc);

    SetCapture(hWnd);

    return 0;

    }

    }

    break;

    case WM_LBUTTONUP:

    if (capture)

    {

    ReleaseCapture(); //Освобождение мыши

    capture = false;

    }

    break;

    case WM_MOUSEMOVE:

    if (capture)

    { //Мышь захвачена

    point.x = LOWORD(lParam);

    point.y = HIWORD(lParam);

    DcInLp(point); //Преобразование экранных координат мыши

    pt[index] = point; // в логические координаты

    InvalidateRect(hWnd, NULL, TRUE);

    }

    break;

    case WM_PAINT:

    hdc = BeginPaint(hWnd, &ps);

    transform(hdc); //Переход в логические координаты

    SelectObject(hdc, hDash);

    Polyline(hdc, pt, count); //Строим ломанную линию

    SelectObject(hdc, hBezier);

    PolySplayn(hdc, pt, count); //Строим кривую Безье

    for (i = 0; i < count; i++)

    { //Закрашиваем точки графика прямоугольниками

    SetRect(&rt, pt[i].x - MARK, pt[i].y - MARK,

    pt[i].x + MARK, pt[i].y + MARK);

    FillRect(hdc, &rt, hRect);

    }

    break;

    case WM_DESTROY:

    DeleteObject(hDash);

    DeleteObject(hBezier);

    DeleteObject(hRect);

    DeleteObject(hSel);

    out.open("dat.txt"); //открыть файловый поток для записи даннах

    for (i = 0; i < count; i++) out << pt[i].x << '\t' << pt[i].y << '\n';

    out.close();

    default:

    return DefWindowProc(hWnd, message, wParam, lParam);

    }

    return 0;

    }

    Результат работы программы отображается на рисунке 3:



    Рис 3. “Безье функция”

    ЗАКЛЮЧЕНИЕ


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


    написать администратору сайта