2015-01-19 13 views
7

Tôi có một trường hợp mà là dựa trên dự một điểm trên một đường thẳng và sau đó tách dòng này vào nó. trường hợp sử dụng của tôi là hơi phức tạp hơn, nhưng vấn đề của tôi có thể được sao chép với đoạn mã sau:Làm thế nào để đối phó với các lỗi làm tròn trong kiểu dáng cân đối

from shapely import * 
line1 = LineString([(1,1.2), (2,2), (3, 2.), (4,1.2)]) 
pt = Point(2.5, 1.2) 
pr = line1.interpolate(line1.project(pt)) 

Bằng cách xây dựng, "pr" nên được trên line1 và ngã tư của họ quá:

line1.contains(pr) 
line1.intersects(LineString([pt, pr])) 

in hai lần "Đúng". Nhưng việc thay đổi tọa độ đầu vào hơi phanh công việc:

from shapely import * 
line1 = LineString([(1,1.2), (2,2), (3, 2.3), (4,1.2)]) 
pt = Point(2.5, 1.2) 
pr = line1.interpolate(line1.project(pt)) 
line1.contains(pr) 
line1.intersects(LineString([pt, pr])) 

in "False".

Tôi hiểu vấn đề chính xác nổi đằng sau điều này, nhưng điều đó có nghĩa là tôi có thể không bao giờ thử nghiệm cho các điểm đang trên đường kẻ? Khi tôi xây dựng một đường dựa trên một danh sách các điểm, tôi có thể chắc chắn rằng ít nhất tất cả các "xây dựng" điểm sẽ được trên dòng?

+0

Bạn có thể lựa chọn một đơn vị cụ thể hơn, cho phép nói, mm thay vì mét? –

+0

@PauloScardine: nhờ. Có, tôi có thể dễ dàng cho đi chính xác nếu tôi đạt được sự ổn định. Multipliying giá trị của tôi bằng 10 làm cho các trick. Nhưng nó sẽ làm việc trong ** tất cả ** trường hợp? Shapely tiếp tục làm việc với phao nổi trong nội bộ. – Fabzi

Trả lời

5

Về cơ bản, cần có precision model và có nhiều kế hoạch khác nhau để triển khai GEOS vào một thời điểm nào đó (đừng nín thở vì điều này đã được thảo luận trong nhiều năm).

Nếu không, các tùy chọn kiểm tra khoảng cách dựa trên (đề nghị) hoặc kỹ thuật đệm dựa trên đắt hơn bởi một sự điều chỉnh nhỏ (xem machine epsilon):

from shapely.geometry import LineString, Point 

line1 = LineString([(1,1.2), (2,2), (3, 2.3), (4,1.2)]) 
pt = Point(2.5, 1.2) 
pr = line1.interpolate(line1.project(pt)) 

# Distance based 
print(line1.distance(pr) == 0.0) # True 

# Buffer based 
EPS = 1.2e-16 
print(line1.buffer(EPS).contains(pr)) # True 
print(line1.buffer(EPS).intersects(LineString([pt, pr]))) # True 

Bạn cũng có thể chuỗi kiểm tra rẻ hơn và đắt tiền sử dụng một or operator , ví dụ:

print(line1.contains(pr) or line1.buffer(EPS).contains(pr)) 

chỉ chạy thử nghiệm thứ hai và đắt hơn nếu lần đầu tiên trả về False.

+0

Hi @MikeT, cảm ơn vì câu trả lời của bạn, đó là những gì tôi đã affraid của. Tôi thực sự muốn chúng tôi có một mô hình chính xác. Hoặc sẽ là thủ thuật làm việc với các số nguyên thay vì nổi (xem nhận xét của Paulo ở trên) đảm bảo sự ổn định? Trường hợp sử dụng của tôi phức tạp hơn và dựa trên các công đoàn: 'shapely.ops.polygonize (LinearRing (line1) .union (LineString ([pt, pr])))' trả về các đa giác khác nhau nếu hai đường cắt nhau hay không ... _ (tôi ước gì có thể upvote câu trả lời của bạn nhưng tôi havn't đủ uy tín cho rằng;) _ – Fabzi

Các vấn đề liên quan