C++ Hình Họa Không Gian: C++ Polygon
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 trước chúng ta đã biết cách xây dựng lớp triangle.
Hôm nay chúng ta sẽ học cách xây dựng lớp polygon.
1. Lý thuyết cơ bản.
a. Tính chất của polygon
Polygon là một đối tượng đa giác khép kín có số lượng điểm từ 3 trở lên.
Như vậy, rect, triangle thực chất là dạng polygon đặc biệt.
Do chúng ta đã định nghĩa rect và triangle riêng biệt, nên trong bài này, chúng ta coi polygon là một đa giác có từ 4 điểm trở lên,
và chúng có thể có dạng đặc biệt như rect hoặc là một hình đa giác bình thường.
Polygon sẽ có một mảng điểm, và một biến lưu trữ số lượng điểm, có thể là 4, 5…
b. Các hàm xử lý cơ bản của Pololygon.
– Hàm khởi tạo: khởi tạo ban đầu giá trị các điểm.
– Hàm hủy.
– Hàm mảng điểm, và số lượng điểm
– Hàm lấy mảng chứa list các điểm, số lượng điểm
– Hàm tính diện tích của Polygon
– Hàm tính chu vi của Polygon.
– Hàm tính ra điểm trọng tâm của Polygon
– Hàm check 1 điểm nằm trong vùng hay ngoài vùng, hay trên cạnh của polygon.
– Hàm trả về kết quả là điểm min, max của bounding box cho polygon
Và các hàm khác các bạn có thể nghĩ ra.
2. Code sample.
File header
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
#ifndef TPOLYGON_H_ #define TPOLYGON_H_ #include <vector> #include "TPoint2D.h" class TPolygon { public: TPolygon(); ~TPolygon(); void AddPoint(TPoint2D& pt); void SetPointList(std::vector<TPoint2D>& list); int GetCount() { return m_points.size(); } float GetPerimeter(); float GetArea(); void GetBounding(TPoint2D& pMin, TPoint2D& pMax); int CheckRelPoint(const TPoint2D& p); TPoint2D GetCentroid(); std::vector<TPoint2D> GetPoint() { return m_points; } private: std::vector<TPoint2D> m_points; }; #endif |
File Cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
#include "TPolygon.h" #include "TTriangle.h" TPolygon::TPolygon() { } TPolygon::~TPolygon() { } void TPolygon::AddPoint(TPoint2D& pt) { m_points.push_back(pt); } void TPolygon::SetPointList(std::vector<TPoint2D>& list) { m_points = list; } float TPolygon::GetPerimeter() { int nSize = m_points.size(); float peri = 0.0; for (int i = 0; i < nSize; i++) { int j = (i + 1) % nSize; float d = m_points[i].GetDistance(m_points[j]); peri += d; } return peri; } // z = 0 float TPolygon::GetArea() { float pArea = 0.0; TPoint2D centroidPt = GetCentroid(); int nSize = m_points.size(); for (int i = 0; i < nSize; i++) { int j = (i + 1) % nSize; TPoint2D p1 = m_points[i]; TPoint2D p2 = m_points[j]; TPoint2D p3 = centroidPt; TTriangle triangle(p1, p2, p3); pArea += triangle.GetArea(); } return pArea; } void TPolygon::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_; int nSize = m_points.size(); for (int i = 0; i < nSize; 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; } ////////////////////////////////////////////////////////////////////////// // return 0: inside // return 1: on line // return 2: out side // Note: polygon 2d: z = 0 ////////////////////////////////////////////////////////////////////////// int TPolygon::CheckRelPoint(const TPoint2D& p) { int nSize = m_points.size(); for (int i = 0; i < nSize; i++) { int j = (i + 1) % nSize; TLine2D pLine(m_points[i], m_points[j]); int ret = pLine.CheckRelPoint(p); if (ret == 0) { return 1; // on line } } float pAre = GetArea(); float checkArea = 0.0; for (int i = 0; i < nSize; i++) { int j = (i + 1) % nSize; TPoint2D p1 = m_points[i]; TPoint2D p2 = m_points[j]; TPoint2D p3 = p; TTriangle triangle(p1, p2, p3); checkArea += triangle.GetArea(); } if (fabs(checkArea - pAre) < TEXP_4) { return 0; // inside } return 2; } TPoint2D TPolygon::GetCentroid() { TPoint2D pt; int n = m_points.size(); float sArea = 0; // For all vertices for (int i = 0; i < n; i++) { float x0 = m_points[i].x_; float y0 = m_points[i].y_; float x1 = m_points[(i + 1) % n].x_; float y1 = m_points[(i + 1) % n].y_; // Calculate value of A // using shoelace formula float A = (x0 * y1) - (x1 * y0); sArea += A; // Calculating coordinates of // centroid of polygon pt.x_ += (x0 + x1) * A; pt.y_ += (y0 + y1) * A; } sArea *= 0.5; pt.x_ = (pt.x_) / (6 * sArea); pt.y_ = (pt.y_) / (6 * sArea); return pt; } |
Ok. Đó là cách mô hình hóa 1 đối tượng polygon bằng kỹ thuật lập trình c++