C++ Hình Họa Không Gian: C++ Rectangle

Hi, chào mừng các bạn trở lại với chủ đề C++ Hình họa không gian.

Bài hôm nay chúng ta sẽ xây dựng một lớp đối tượng mới, đó là lớp rectangle.

Như vậy khi các bạn đã có point, vector, line rồi, chúng ta có thể tạo ra các lớp đối tượng hình học theo như mong muốn

Và bài hôm nay, tôi sẽ xây dựng lớp rectangle.

1. Lý thuyết cơ bản.

a. Tính chất của rect

Rectangle hay còn gọi là hình chữ nhât có các tính chất cơ bản sau.

– Rect luôn bao gồm 4 điểm => lớp sẽ có 4 point.

– Rect có thể sử dụng 2 điểm để tạo ra 4 điểm còn lại, ví dụ điểm min, max.

– Rect thường là yếu tố hình học đại diện cho vùng bao của một đối tượng hình học khác.

b. Các hàm xử lý cơ bản của Rect.

– Hàm khởi tạo: khởi tạo ban đầu giá trị các điểm.

– Hàm hủy.

– Hàm sét giá trị các điểm.

– Hàm lấy mảng chứa list các điểm.

– Hàm tính diện tích của rect

– Hàm tính chu vi của rect.

– Hàm tính ra điểm trọng tâm của rect.

– Hàm check một điểm nằm bên trong của rect hay bên ngoài rect, hay trên cạnh của rect.

Và các hàm khác các bạn có thể nghĩ ra.

2. Code sample

File header.

#include <vector>
#include "TPoint2D.h"
#include "TLine.h"

class TRect
{
public:
    TRect();
    ~TRect();
    void ChangePoint(TPoint2D& p, int index);
    void SetPoint(TPoint2D* p);
    TPoint2D* GetPoint(int& nSize);
    std::vector<TPoint2D> GetPointList();
    float GetArea();
    float GetPerimiter();
    TPoint2D GetCenterPt();
    
    // Condition: z = 0 (2D)
    // return = -1 => No Define
    // return = 0 => inside
    // return = 1 => in edge
    // return = 2 => outside
    int CheckRelPoint(const TPoint2D& p);
    void GetBounding(TPoint2D& pMin, TPoint2D& pMax);
private:
    TPoint2D m_points[4];
};

File Cpp

#include "TRect.h"


TRect::TRect()
{
    for (int i = 0; i < 4; i++)
    {
        m_points[i] = TPoint2D(0.0, 0.0);
    }
}


TRect::~TRect()
{

}
void TRect::ChangePoint(TPoint2D& p, int index)
{
    if (index >= 0 && index < 4)
    {
        m_points[index] = p;
    }
}

void TRect::SetPoint(TPoint2D* p)
{
    for (int i = 0; i < 4; i++)
    {
        m_points[i] = *(p + i);
    }
}

TPoint2D* TRect::GetPoint(int& nSize)
{
    nSize = 4;
    return &m_points[0];
}

std::vector<TPoint2D> TRect::GetPointList()
{
    std::vector<TPoint2D> ptList;
    ptList.push_back(m_points[0]);
    ptList.push_back(m_points[1]);
    ptList.push_back(m_points[2]);
    ptList.push_back(m_points[3]);

    return ptList;
}

float TRect::GetArea()
{
    float d1 = m_points[0].GetDistance(m_points[1]);
    float d2 = m_points[1].GetDistance(m_points[2]);
    float s = d1*d2;
    return s;
}

float TRect::GetPerimiter()
{
    float d1 = m_points[0].GetDistance(m_points[1]);
    float d2 = m_points[1].GetDistance(m_points[2]);
    float c = (d1 + d2) * 2;
    return c;
}

TPoint2D TRect::GetCenterPt()
{
    TPoint2D ptMid = m_points[0].GetMidPoint(m_points[2]);
    return ptMid;
}

int TRect::CheckRelPoint(const TPoint2D& p)
{
    bool iret = -1;
    for (int i = 0; i < 4; i++)
    {
        int j = (i + 1) % 4;
        TLine2D line = TLine2D(m_points[i], m_points[j]);
        int ret = line.CheckRelPoint(p);
        if (ret == 0)
        {
            iret = 1; // in line
            return iret;
        }
    }

    int xMin = m_points[0].x_;
    int yMin = m_points[0].y_;
    int xMax = m_points[0].x_;
    int yMax = m_points[0].y_;

    for (int i = 0; i < 4; i++)
    {
        if (xMin > m_points[i].x_)
        {
            xMin = m_points[i].x_;
        }

        if (yMin > m_points[i].y_)
        {
            yMin = m_points[i].y_;
        }

        if (xMax < m_points[i].x_)
        {
            xMax = m_points[i].x_;
        }

        if (yMax < m_points[i].y_)
        {
            yMax = m_points[i].y_;
        }
    }

    if (p.x_ > xMin && p.x_ < xMax &&
        p.y_ > yMin && p.y_ < yMax)
    {
        return 0;
    }
    else
    {
        return 2;
    }

    return -1;
}

void TRect::GetBounding(TPoint2D& pMin, TPoint2D& pMax)
{
    float xmin = m_points[0].x_;
    float ymin = m_points[0].y_;
    float xmax = m_points[0].x_;
    float ymax = m_points[0].y_;

    for (int i = 0; i < 4; i++)
    {
        float x = m_points[i].x_;
        float y = m_points[i].y_;

        if (x > xmax)
        {
            xmax = x;
        }

        if (y > ymax)
        {
            ymax = y;
        }

        if (x < xmin)
        {
            xmin = x;
        }

        if (y < ymin)
        {
            ymin = y;
        }
    }

    pMin.x_ = xmin;
    pMin.y_ = ymin;

    pMax.x_ = xmax;
    pMax.y_ = ymax;

}

 

Khi độ dài các cạnh là bằng nhau, rect sẽ trở thành một hình vuông. Do đó các bạn có thể sử dụng cho cả hình vuông

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.