Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Рисование геометрических фигур в консольном приложении (vs2005)

10K
14 ноября 2007 года
Omega Red
49 / / 15.10.2006
Нужно реализовать рисование какой-нибудь геометрической фигуры, передвижение и другие функции по желанию. Вот код написанной программы:
shape.h
Код:
#pragma once;
#include <iostream>
using namespace std;
#include <windows.h>
#include <atlstr.h>
#include <cstring>

enum Direction {LEFT, RIGHT, UP, DOWN};
class Shape
{
public:
    Shape();
    virtual ~Shape() = 0;
    virtual double  square() = 0;
    virtual void    draw() = 0;
    virtual void    move(Direction, int) = 0;
    virtual int     IsInside(int x, int y) = 0;
protected:
    HWND hwnd;
    HDC hdc;
    COLORREF color;
    int left, top, right, bottom;
    CString str;
};


shape.cpp
Код:
#include <iostream>
using namespace std;
#include <conio.h>
#include "shape.h"

Shape::Shape()
{
    hwnd = 0;
    SetConsoleTitle((LPCWSTR) L"Shape");

        if ((hwnd = FindWindow(NULL, (LPCWSTR) L"Shape")) == 0)
        {
            cout<<"Window not found!!!"<<endl;
            return;
        }

        if ((hdc = GetDC(hwnd)) == 0)
        {
            cout<<"O6ibka!!!"<<endl;
            return;
        }
}
/////////////////////////////////////////////////////////
Shape::~Shape()
{
    ReleaseDC(hwnd,hdc);
}


circle.h
Код:
#pragma once;
#include "shape.h"

class Circle : public Shape
{
private:
    int cx, cy, radius;
public:
    Circle(int x = 0, int y = 0, int r = 0, COLORREF c = RGB(0,0,0));
    void   draw();
    void   move(Direction, int);
    double square();
    int    IsInside(int x, int y);
};


circle.cpp
Код:
#include "circle.h"
#include <conio.h>

Circle::Circle(int x, int y, int r, COLORREF c) : Shape()
{
    cx    = x; cy = y;   radius = r;
    color = c;
    left  = cx - radius; top    = cy - radius;
    right = cx + radius; bottom = cy + radius;

}

void Circle::draw()
{
    HPEN    pen;
    HBRUSH  brush;
    pen   = CreatePen(PS_SOLID, 2, RGB(0,150,0));
    brush = CreateSolidBrush(color);

    SelectObject(hdc, pen); SelectObject(hdc, brush);

    Ellipse(hdc, cx - radius, cy - radius, cx + radius, cy + radius);

    DeleteObject(pen); DeleteObject(brush);
}

int Circle::IsInside(int x, int y)
{return (x - cx) * (x - cx) + (y - cy) * (y - cy) <= radius * radius;}

double Circle::square()
{return 3.1415926536 * radius * radius;}


void Circle::move(Direction way, int distance)
{
    InvalidateRect(hwnd, NULL, 1);
    switch(way)
    {
    case LEFT:
        str = " Влево";
        cx -= distance;
        break;
    case RIGHT:
        str = "Вправо";
        cx += distance;
        break;
    case UP:
        str = "Вверх";
        cy -= distance;
        break;
    case DOWN:
        str = "Вниз";
        cy += distance;
        break;
    default:break;
    }

        TextOut(hdc,200,1,str,20);
}


triangle.h
Код:
#pragma once;
#include "shape.h"
#include <cmath>

class Triangle : public Shape
{
protected:
    int x1, y1, x2, y2, x3, y3;
public:
    Triangle(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0, int x3 = 0,             int y3   = 0, COLORREF c = RGB(0,0,0));
    void   draw();
    void   move(Direction, int);
    double square();
    int    IsInside(int x, int y);

};


triangle.cpp
Код:
#include "triangle.h"

Triangle::Triangle(int x1, int y1, int x2, int y2, int x3, int y3, COLORREF c)
{
    this->x1 = x1;
    this->y1 = y1;
    this->x2 = x2;
    this->y2 = y2;
    this->x3 = x3;
    this->y3 = y3;
    color  = c;
    left   = min(x1, x2, x3);
    top    = min(y1, y2, y3);
    right  = max(x1, x2, x3);
    bottom = max(y1, y2, y3);
}

void Triangle::draw()
{
    HPEN    pen;
    HBRUSH  brush;
    POINT points[] = {{x1, y1}, {x2, y2}, {x3, y3}};

    pen   = CreatePen(PS_SOLID, 3, RGB(0,0,150));
    brush = CreateSolidBrush(color);

    SelectObject(hdc, pen); SelectObject(hdc, brush);

    Polygon(hdc, points, 3);

    DeleteObject(pen); DeleteObject(brush);
}

int Triangle::IsInside(int x, int y)
{
    Triangle
        t1(x1, y1, x2, y2, x, y),
        t2(x1, y1, x3, y3, x, y),
        t3(x2, y2, x3, y3, x, y);

  if (fabs(square() - t1.square() - t2.square() - t3.square()) < 0.001)
     return 1;
  else
     return 0;
}

double Triangle::square()
{return fabs((double)((x2 - x1)*(y3 - y1) - (x3 - x1)*(y2 - y1))) / 2;}

void Triangle::move(Direction way, int distance)
{
    InvalidateRect(hwnd, NULL, 1);

    switch(way)
    {
    case LEFT:
        str = "Влево";
        x1 -= distance;
        x2 -= distance;
        x3 -= distance;
        break;
    case RIGHT:
        str = "Вправо";
        x1 += distance;
        x2 += distance;
        x3 += distance;
        break;
    case UP:
        str = "Вверх";
        y1 -= distance;
        y2 -= distance;
        y3 -= distance;
        break;
    case DOWN:
        str = "Вниз";
        y1 += distance;
        y2 += distance;
        y3 += distance;
        break;
    default:break;
    }
     TextOut(hdc,200,1,str,20);
}


driver.cpp
Код:
#include <conio.h>
#include "circle.h"
#include "triangle.h"


void main()
{
    Shape *myShape[2] = {
        new Circle(300,100,50, RGB(100,0,200)),
        new Triangle(150,100,100,200,200,200, RGB(200,40,10))
    };

    Shape *WShape = myShape[0];

    myShape[0]->draw();
    myShape[1]->draw();

    while(1)
    {
        int c;
        //int x = 0;
        c = getch();
        //c = getch();
       
        switch(c)
        {
        case 49: //1
            //x = 0;
            WShape = myShape[0];
            break;
        case 50: //2
            //x = 1;
            WShape = myShape[1];
            break;
        case 75: //Влево
            WShape->move(LEFT, 10);
            break;
        case 77: //Вправо
            WShape->move(RIGHT, 10);
            break;
        case 72: //Вверх
            WShape->move(UP, 10);
            break;
        case 80: //Вниз
            WShape->move(DOWN, 10);
            break;
        }
        WShape->draw();
    }
}



Программа работает, при нажатии на клавиши 1 и 2 происходит переключение между кругом и треугольником, после чего можно перемещать по окну.
Вот некоторые появившиеся вопросы:
1) Не найдя никакой функции для очистки экрана, я попробовал использовать InvalidateRect(hwnd, NULL, 1);, и на удивление заработало. Что делает эта функция?
2) Как сделать так, чтобы при переключении на другую фигуру первая не исчезала, а оставалась?
3) Как запретить перемещение фигуры за границы окна?
4) Я пробовал реализовать изменение цвета при нажатии на клавишу +, сделал функцию изменения цвета, которая получает 3 переменные int, но не знаю как изменить данные в типе COLORREF.
5) В одном примере я видел следующий код:
 
Код:
case ID_CIRCLE:
    if (DialogBox(hInst, (LPCTSTR)IDD_NEWCIRCLE, hWnd, (DLGPROC)NewCircle) == IDOK)
{...создание и прорисовка круга...}

Как работает данная конструкция?
6) Почему функция TextOut выводит после нужной надписи множество символов "Ъ"?
7) Можно ли создать надпись с информацией о площади фигуры без использования преобразования числа в строку и функции TextOut?
8) На лекции в примере нажатие клавиш получали 2 функции getch() подряд, потому что здесь специальная обработка какая-то, но оно работает и с одной функцией, нужна ли 2 функция?
13K
15 ноября 2007 года
specter
113 / / 28.09.2007
Попробую ответить на твои вопросы ;)
1) Читай msdn
2) в driver.cpp ты вызываешь WShape->draw(); т.е. прорисовку только одного объекта! вызови прорисовку второго и будет тебе счастье ;)
3) mfc не помню, но границы окна точно можно узнать без проблем ;) так что msdn
4) на сколько я помню - colorref это всего-то 4х байтное число... так что чтобы получить значение делаешь (r << 16) | (g << 8) | b
5) И снова тебе путь в msdn
6) а ты какие параметры передаешь ей? TextOut(hdc,200,1,str,20)... последний параметр это случайно не длина строки?
7) в mfc - нет
8) не нужна
10K
15 ноября 2007 года
Omega Red
49 / / 15.10.2006
1) прочитал, ничего конкретного не сказали, только поверхностно
3)тут я даже не знаю что писать для поиска, поэтому пока просто не буду вылазить за пределы
5) Я в этой строчке каждый параметр не понял, так что от мсдн никакой помощи
6) Последний параметр это длина строки, но если небольшое число, то обрезает, а если много то заполняет лишними символами
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог