Câu hỏi

Cho trục toạ độ Oxy. Một Tam giác hiểu là 3 toạ độ (a, b), (c, d), (m, n) trên mặt phẳng. Viết chương trình kiểm tra một điểm (x, y) có nằm trong tam giác hay không?

Bài giải

Với cách tiếp cận OOP, chúng ta cần định nghĩa class Point, Line, Triangle.
Phải xây dựng Class / Object trước, sau đó mới xây dựng Thuật toán.

<?php
class Point
{
    public int $x;
    public int $y;

    // kiểm tra 2 Point có bằng nhau không
    public function isEqual(Point $p): bool
    {
        return $p->x === $this->x && $p->y === $this->y;
    }
}

class Line
{
    public Point $p1;
    public Point $p2;
    
    /**
     * Tính độ dài đoạn thẳng theo công thức khoảng cách Euclid:
     * căn((x2 - x1)² + (y2 - y1)²)
     */
    public function length()
    {
        $dx = $this->p2->x - $this->p1->x;
        $dy = $this->p2->y - $this->p1->y;
        return sqrt($dx ** 2 + $dy ** 2);
    }    

    public static function create(Point $p1, Point $p2): Line
    {
        // kiểm tra 2 điểm không được trùng nhau
        if ($p1->isEqual($p2)) {
            return null;
        }
        $line = new Line();
        $line->p1 = $p1;
        $line->p2 = $p2;
        return $line;
    }
    
}

class Triangle
{
    public Point $a;
    public Point $b;
    public Point $c;
    
    public static function create(Point $a, Point $b, Point $c): static
    {
        // bổ sung kiểm tra 3 điểm không trùng nhau ở đây
        $triangle = new Triangle();
        $triangle->a = $a;
        $triangle->b = $b;
        $triangle->c = $c;
        return $triangle;
    }

    
    /**
     * Tính diện tích tam giác theo công thức Heron.
     */
    public function area(): float
    {
        $ab = (new Line($this->a, $this->b))->length();
        $bc = (new Line($this->b, $this->c))->length();
        $ca = (new Line($this->c, $this->a))->length();

        $p = ($ab + $bc + $ca) / 2; // nửa chu vi

        return sqrt($p * ($p - $ab) * ($p - $bc) * ($p - $ca));
    }
}

Sau khi mô tả xong các class với function tính diện tích tam giác đã có bằng công thức Heron, chúng ta có thể suy luận như sau: một điểm nằm trong tam giác khi tổng diện tích 3 tam giác con tạo ra bé hơn bằng diện tích tam giác.

như vậy ta chỉ cần bổ sung thêm code vào class Triangle

<?php
class Triangle
{
    // ... các code ở trên đã có
    public function isContains(Point $p): bool
    {
        $areaABC = $this->area();
        $areaPAB = (new Triangle($p, $this->a, $this->b))->area();
        $areaPBC = (new Triangle($p, $this->b, $this->c))->area();
        $areaPCA = (new Triangle($p, $this->c, $this->a)->area();

        $sum = $areaPAB + $areaPBC + $areaPCA;

        // Sai số do số thực floating point
        return abs($sum - $areaABC) < 1e-6;
    }

}

By admin