Hướng dẫn tìm hiểu về tính diện tích tam giác trong lập trình
Trong lập trình thuật toán, hình học là một chủ đề rất quan trọng và ứng dụng cao. Tuy nhiên, nó cũng là một chủ đề khá khó. Trong bài viết này, chúng ta sẽ cùng nhau tìm hiểu vấn đề đầu tiên liên quan đến hình học - tính diện tích tam giác.
Chuẩn bị kiến thức cần thiết
Để hiểu bài viết này một cách tốt nhất, bạn nên có kiến thức cơ bản về:
- Các kiến thức cần thiết để theo dõi khóa học
Trên cơ sở kiến thức này, chúng ta sẽ cùng tìm hiểu về tính diện tích của tam giác.
Vấn đề đặt ra
Trên hệ tọa độ Descartes, cho trước một tam giác gồm 3 đỉnh. Nhiệm vụ của chúng ta là tính diện tích tam giác đã cho.
Input:
- Gồm 3 dòng, mỗi dòng chứa 2 số nguyên dương (Xi, Yi)
- 0 ≤ Xi, Yi ≤ 10^5
Output:
- Một số thực duy nhất là diện tích tam giác đã cho, làm tròn đến 1 chữ số phần thập phân.
Ví dụ: Input: 2 1 6 2 3 4 5 5
Output: 7.5
Giải thích ví dụ: Đây là tam giác đã cho trên hệ tọa độ Descartes.
Ý tưởng
Ta có thể tính diện tích tam giác thông qua tính chiều cao và cạnh đáy, tuy nhiên, phương pháp này khá khó khăn. Một lựa chọn khác là áp dụng công thức Heron. Tuy nhiên, trong bài viết này, mình sẽ giới thiệu một phương pháp tính khác, đơn giản và có ứng dụng cao hơn.
Cách cài đặt
Để lưu trữ các điểm, bạn có thể sử dụng bất kỳ cấu trúc dữ liệu nào lưu trữ được hai phần tử. Trong bài này, mình sẽ xây dựng một cấu trúc dữ liệu Point
với 2 biến x
và y
thể hiện toạ độ của một điểm.
struct Point {
int x, y;
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
};
Để tránh xử lí với số thực quá nhiều, ta sẽ nhân cả hai vế của công thức 2 * S_ABC = (AM + NC) * MN + (CN + BP) * NP - (AM + BP) * MP
với 2. Khi đó, 2 * S_ABC = ((Y_A - Y_M) + (Y_C - Y_N)) * (X_N - X_M) + ((Y_C - Y_N) + (Y_B - Y_P)) * (X_P - X_N) - ((Y_A - Y_M) + (Y_B - Y_P)) * (X_P - X_M)
.
Ta thấy A và M có cùng tung độ. Do đó, độ dài AM là hiệu hoành độ của A và M. Tương tự, M và N có cùng tung độ, nên độ dài MN là hiệu hoành độ của M và N hoặc chính là hiệu hoành độ của C và A.
Do vậy, 2 * S_ABC = ((Y_A - Y_M) + (Y_C - Y_N)) * (X_C - X_A) + ((Y_C - Y_N) + (Y_B - Y_P)) * (X_B - X_C) + ((Y_A - Y_M) + (Y_B - Y_P)) * (X_A - X_B)
.
Tổng quát hơn, ta có công thức sau:
Gọi (X_1, Y_1), (X_2, Y_2), (X_3, Y_3) lần lượt là toạ độ 3 đỉnh của một tam giác. Khi đó, diện tích tam giác đó được xác định như sau:
S = (Y_2 + Y_1) * (X_2 - X_1) + (Y_3 + Y_2) * (X_3 - X_2) + (Y_1 + Y_3) * (X_1 - X_3)
Dưới đây là đoạn code cài đặt:
#include
using namespace std;
typedef long long ll;
struct Point {
int x, y;
Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
};
ll area(Point a, Point b, Point c) {
return (a.y + b.y) * (b.x - a.x) + (c.y + b.y) * (c.x - b.x) + (a.y + c.y) * (a.x - c.x);
}
int main() {
freopen("CTDL.inp","r",stdin);
freopen("CTDL.out","w",stdout);
Point A, B, C;
cin >> A.x >> A.y;
cin >> B.x >> B.y;
cin >> C.x >> C.y;
ll ans = area(A, C, B);
if(ans % 2)
cout << ans / 2 << ".5" << endl;
else
cout << ans / 2 << ".0" << endl;
return 0;
}
Vấn đề kế tiếp
Mình để lại một vấn đề cho các bạn để thảo luận:
Trong đoạn code trên, ta đang đặt thứ tự các đỉnh trong hàm là A, C, B. Điều gì sẽ xảy ra nếu thay đổi thứ tự đỉnh thành A, B, C? Hãy làm thử để tìm hiểu nguyên nhân và ý nghĩa của vấn đề này nhé.
Kết luận
Qua bài viết này, chúng ta đã tìm hiểu về cách tính diện tích tam giác. Bài viết tiếp theo chúng ta sẽ tiếp tục tìm hiểu về tính diện tích tam giác với một số tính chất thu được từ diện tích tam giác.
Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên "Luyện tập - Thử thách - Không ngại khó".
Thảo luận
Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bình luận bên dưới hoặc trong mục hỏi và đáp trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.