Về vấn đề vectơ pháp tuyến và điểm ngẫu nhiên trên mặt phẳng với ngôn ngữ Python

Trong một video tôi mới làm gần đây, liên quan đến việc nhận biết phương trình mặt phẳng trong không gian $Oxyz$ bằng ngôn ngữ Python, có hai vấn đề vẫn chưa được giải quyết triệt để:

  • Một là, việc rút gọn tọa độ vectơ pháp tuyến cho tiện khi giải toán vấn chưa được đưa vào, khiến cho chương trình có vẻ như chưa được trọn vẹn.
  • Hai là, việc truy tìm tọa độ nguyên của một điểm ngẫu nhiên trên mặt phẳng vẫn còn lỗ hổng. Trong trường hợp không thể tìm thấy tọa độ nguyên, vòng lặp while sẽ diễn ra vô tận, thậm chí treo máy. Khi này, ta đành buộc ngừng lệnh while và chấp nhận một tọa độ không nguyên nào đó.

Cho những ai chưa xem video này, các bạn có thể xem qua nội dung dưới đây:

Sau đây, tôi sẽ đề xuất cách giải quyết cho hai vấn đề trên.

Rút gọn tọa độ của vectơ pháp tuyến

Trong trường hợp tọa độ $(a;b;c)$ của vectơ pháp tuyến (hoặc vectơ chỉ phương) có các thành phần nguyên tố cùng nhau, ta thường rút gọn chúng để được một vectơ mới có độ dài nhỏ hơn. Cụ thể, nếu ước chung lớn nhất của $a$, $b$, $c$ là một số nguyên lớn hơn $1$, ta sẽ chia cả ba cho ước chung này. Vậy hàm  normalVector  sẽ được viết lại như sau:

    def normalVector(self):
        v = self.coefficient()
        v.pop()
        ucln = gcd(v)
        a = v[0]/ucln
        b = v[1]/ucln
        c = v[2]/ucln
        return [a,b,c]

Lệnh gcd này nằm trong thư viện sympy, đối số truyền vào là một list (v) gồm 3 phần tử (a,b,c). Kết quả trả về của hàm này là một list mới, cũng là bộ tọa độ của một vectơ pháp tuyến.

Kiểm soát vòng lặp while khi tìm tọa độ nguyên ngẫu nhiên

Hãy xem xét phương trình mặt phẳng $2x-6y+4z-5=0$. Bởi vì các hệ số $a,b,c$ đều chẳn mà hệ số $d$ lẻ nên không thể nào có tọa độ nguyên nào thỏa phương trình này. Nếu không dừng vòng lặp while, nó sẽ chạy mãi mãi mà không thể in ra kết quả. Giải pháp đưa ra là cho vòng lặp thực hiện tối đa một số lần nào đó, nếu hết số vòng tối đa mà vẫn chưa tìm thấy tọa độ nguyên thì buộc dừng lại, khi đó chương trình sẽ chạy tiếp với kết quả hữu tỉ.

    def randomPoint(self):
        coefs = self.coefficient()
        x0 = rd.randint(-9,9)
        y0 = rd.randint(-9,9)
        if coefs[2] != 0:
            z0 = -(coefs[0]*x0+coefs[1]*y0+coefs[3])/coefs[2]
            loop = 0
            while simplify(z0).is_integer == False and loop<100:
                x0 = rd.randint(-9,9)
                y0 = rd.randint(-9,9)
                z0 = -(coefs[0]*x0+coefs[1]*y0+coefs[3])/coefs[2]
                loop +=1
        elif coefs[1] != 0:
            z0 = rd.randint(-5,5)
            y0 = -(coefs[0]*x0+coefs[3])/coefs[1]
            loop = 0
            while simplify(y0).is_integer == False and loop<100:
                x0 = rd.randint(-9,9)
                y0 = -(coefs[0]*x0+coefs[3])/coefs[1]
                loop +=1
        else:
            z0 = rd.randint(-5,5)
            y0 = rd.randint(-5,5)
            x0 = -coefs[3]/coefs[0]
        return [x0,y0,z0]

Tôi đưa vào biến loop để đếm số vòng lặp, cứ mỗi lần chạy lệnh while, giá trị của biến này tăng 1 đơn vị. Nếu quá 100 vòng thì buộc dừng (do không thỏa điều kiện của lệnh while).

Mặc dù đây chỉ là một lớp đối tượng nhỏ so với cả chương trình toán nhưng chương trình cũng đã giải quyết được một số vấn đề cốt lõi của chủ đề Phương pháp tọa độ trong không gian, đây sẽ là tiền đề tốt giúp ta mở rộng vấn đề thành những bài toán mới.

Bình luận

Chia sẻ