01/10/2018, 14:25

Tính diện tích hình theo pixels

Chào các bạn,
Mình đang gặp vấn đề sau, cứ tưởng đã được giải quyết nhưng hôm nay phát hiện ra thì mình cứng người.

Hình dưới, cột Area là diện tích theo pixels của hình "vuông "lấy theo hàm computedAreaInScreen() trong javafx.

Diện tích hình vuông vẽ align là đúng

Nhưng… hình dưới (re-shape tại 1 góc)

hàm computedAreaInScreen() trả về Diện tích không đổi

Mọi ý tưởng, công sức mấy tháng nay của mình sẽ vào thùng rác nếu ko giải quyết đc diện tích của mình bất kỳ

Các bạn phát hiện ra tại sao hoặc có giải pháp gợi ý giúp mình với?

Liệu đếm số pixels của hình có phải là 1 phương án không?

Quân viết 16:38 ngày 01/10/2018

Hàm computedAreaInScreen() là diện tích của hình chữ nhật bao quanh các cạnh/đỉnh nhỏ nhất chứ không phải diện tích thực của hình

anon45952904 viết 16:39 ngày 01/10/2018

Mình chết tử khi bắt đầu với hiểu lầm này Có cách ko bạn?
Update: Sao cái tên hàm thế có chết ko cơ chứ !

Dark.Hades viết 16:30 ngày 01/10/2018

https://www.mathopenref.com/coordpolygonarea2.html

Thử cái này xem

Hoặc Google:

  • compute area of polygon
anon45952904 viết 16:40 ngày 01/10/2018

Mình làm function để vẽ các hình kỳ quái chết tiệt như thế này:

Tụi kiến trúc sư bây giờ vẽ ra đủ thứ kỳ dị mà nếu là trước đây thì gọi là bullshit.

Tao Không Ngu. viết 16:32 ngày 01/10/2018

HI thanhpv.
Theo mình ý tưởng tính theo pixel hay theo các hình bạn vẽ trong trường hợp như thiết kế hay kiến trúc là không hợp lý.

  1. Việc bạn vẽ hình chỉ là biểu diễn rời rạc của các hình liên tục nên nếu tính diện tích bàng diện tích hình vẽ ra là không chính xác.
  2. Nên xây dựng một mô hình thực ở dưới và tính tioán thuần trên các mo hình đó tách rồi với việc hiển thị đồ họa nó.
anon45952904 viết 16:41 ngày 01/10/2018

Đó là 1 hình SVG duy nhất bạn ạ. Theo tính toán ban đầu của mình là lấy số pixels hiển thị đưa tỉ lệ, đơn vị vào để tính ra diện tích thực.

Tao Không Ngu. viết 16:37 ngày 01/10/2018

Hi thanhpv.

  1. Hình của bạn kiểu gì thì cũng là tập hợp các đường.
  2. Vấn đề là trong đồ họa máy tính các điển là số nguyên và các đường thực bạn vẽ là số thực nên nó sẽ làm tròn khi bạn zoom một ảnh PNG bạn sẽ thấy. Không phải tự nhiên mà file ảnh của bạn là SVG nó là tập hợp các công thức vẽ đương thẳng và cong để đảm bảo khi bạn zoom thì nó sẽ vẽ lại theo công thức để đảm bảo không bị vỡ hình như các định dạng khác.
en.wikipedia.org

Scalable Vector Graphics

Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation. The SVG specification is an open standard developed by the World Wide Web Consortium (W3C) since 1999. SVG images and their behaviors are defined in XML text files. This means that they can be searched, indexed, scripted, and compressed. As XML files, SVG images can be created and edited with any text editor, as well as with drawing software. All major ...

anon45952904 viết 16:30 ngày 01/10/2018

Mình cũng đã hình dung qua về vấn đề này. Nhưng bản chất pm này là vẽ hình trên screen để đưa ra diện tích, chiều dài.

Mình chưa đi sâu vào tính toán sai số của nó. Nhưng chính các phần mềm đo vẽ lớn trên TG cũng không thể đưa ra phép đo hoàn toàn chính xác trên màn hình, luôn có sai số và làm tròn.

Kế hoạch của mình là nâng cao tỉ lệ pixels / unit (mm), tỉ lệ này càng cao thì phép đo càng chính xác.
=> Vấn đề là: Background kia nên có format dạng Scalable Vector.

Update: Nó chính là file PDF bản vẽ, mà hiển thị trực tiếp PDF trong Java thì mình chưa biết làm cách nào

viết 16:27 ngày 01/10/2018

vẽ được cái hình kia ko lẽ ko tách cái hình đó ra vẽ riêng vô 1 trang giấy trắng được?

anon45952904 viết 16:36 ngày 01/10/2018

Mình ko hiểu ý bạn?

Lần đầu tiên mình thực sự làm 1 cái app. Mình chỉ hình dung đường đi cơ bản rồi dần dần giải quyết từng bước. Cái mình tập trung làm thì mình biết còn những thứ chưa đụng đến thì cơ bản vẫn như hố đen. . Đôi khi những thứ mình làm ra ko dễ, nhưng cùng lúc đó có những thứ người khác thấy rất dễ nhưng mình lại chưa biết.

Mình chỉ nghĩ ra cách đếm pixels của hình. Nhưng cách làm mình ko áp dụng đc “count on the fly” vì nó khá expensive.

viết 16:37 ngày 01/10/2018

thế làm sao bạn vẽ được cái hình màu xanh dương kia lên màn hình? Ngoài việc vẽ ra bây giờ bạn lưu history của các bước vẽ lại vô 1 cái list, ví dụ ["ADD(x1 y1)", "CURVE(x2 y2)", ...] rồi lấy cái list này vẽ hình vô 1 trang giấy trắng, rồi đếm số pixel đen chia cho tổng số pixel. Hoặc cũng có thể xài DFS/BFS loang pixel đen ra mà đếm, tránh đếm mấy pixel trắng thừa, nhưng chắc cũng ko lẹ hơn được bao nhiêu

mà chắc đây là cách bạn đang làm? Đếm pixel kiểu này chậm nhưng chấp đủ loại hình. Nếu vừa vẽ vừa tính diện tích “on the fly” thì cho user lựa chọn DPI thấp tới cao chính xác cao thì chậm, thấp thì lẹ.

Tao Không Ngu. viết 16:26 ngày 01/10/2018

Hi thanhpv.

Nhưng chính các phần mềm đo vẽ lớn trên TG cũng không thể đưa ra phép đo hoàn toàn chính xác trên màn hình, luôn có sai số và làm tròn.

  1. Cái này không chắc nhé.
    “Kế hoạch của mình là nâng cao tỉ lệ pixels / unit (mm)”
  2. Cái này cần phải xem lại.
  3. Đếm pixel thì bạn có thể xem các giải thuật tô màu / loang màu.
anon45952904 viết 16:32 ngày 01/10/2018

“Kế hoạch của mình là nâng cao tỉ lệ pixels / unit (mm)”
Cái này cần phải xem lại.

Cái này sao ko ổn à bạn? mình đang tìm cách phóng to PDF lên để tăng độ chính xác.

anon45952904 viết 16:33 ngày 01/10/2018

Mỗi hình là 1 object riêng biệt nên mình ko phải giải quyết vấn để về màu pixel. Các điểm ko có màu đều ko thuộc object.

Mình hiện đang loop lồng 2 chiều đơn giản để đếm pixels. Mình thấy hơi chậm, các bạn từng trải qua thuật toán chỉ giúp mình có thuật toán nào nhanh hơn không.

viết 16:41 ngày 01/10/2018

2 vòng for loop bao nhiêu pixel tổng cộng? 4000x3000 pixels à @_@

tìm cách nào tính ra được cái bounding box của cái hình, vi dụ x456y123w600h400, rồi vòng for chỉ loop trong cái bounding box đó ~600x400 pixel thì lẹ hơn.

anon45952904 viết 16:40 ngày 01/10/2018

Mình chỉ loop cái bounding box mà. Nhưng nhiều cái bounding box nó lớn hơn thế nhiều.
Hiện chỗ này đang là cái nút cổ chai, mỗi khi lệnh tính được gọi (hoàn thành vẽ, re-shape) là nó lại “đơ”, do tốc độ thuật toán chứ ko ngốn resource.
Mình chưa làm concurrency, có thể đưa việc tính diện tích này sang 1 subtask đc ko bạn? Nó có giải quyết đc tình trạng đơ trên ko?

Bài liên quan
0