Seperti yang Anda lihat pada gambar, pertanyaannya adalah:
Bagaimana menemukan minimum-area-rectangle (MAR) terpasang pada poin yang diberikan?
dan pertanyaan pendukung adalah:
Apakah ada solusi analitis untuk masalah ini?
(Pengembangan pertanyaan adalah mencocokkan kotak (3D) ke sekelompok titik di awan titik 3D.)
Sebagai tahap pertama saya mengusulkan untuk menemukan cembung-hull untuk poin-poin yang mereformasi masalah (dengan menghilangkan titik-titik tersebut tidak terlibat dalam solusi) untuk: memasang MAR ke poligon. Metode yang diperlukan akan memberikan X ( pusat persegi panjang ), D ( dua dimensi ) dan A ( sudut ).
Proposal saya untuk solusi:
- Temukan pusat massa poligon (lihat Pusat penemuan geometri objek? )
- [S] Pas dengan persegi panjang sederhana, sejajar dengan sumbu X dan Y
- Anda dapat menggunakan
minmax
fungsi untuk X dan Y dari poin yang diberikan (mis., simpul poligon)
- Anda dapat menggunakan
- Simpan area persegi panjang yang dipasang
- Putar poligon tentang centroid dengan misalnya 1 derajat
- Ulangi dari [S] hingga rotasi penuh selesai
- Laporkan sudut area minimum sebagai hasilnya
Bagi saya itu tampak menjanjikan, namun masalah berikut ada:
- memilih resolusi yang baik untuk perubahan sudut bisa jadi menantang,
- biaya perhitungannya tinggi,
- solusinya bukan analitis tetapi eksperimental.
Untuk melengkapi solusi hebat @ julien, berikut ini adalah implementasi
R
yang berfungsi, yang dapat berfungsi sebagai pseudocode untuk memandu implementasi spesifik GIS (atau diterapkan langsungR
, tentu saja). Input adalah array koordinat titik. Output (nilai darimbr
) adalah array dari simpul persegi panjang batas minimum (dengan yang pertama diulang untuk menutupnya). Perhatikan tidak adanya perhitungan trigonometri.Berikut ini adalah contoh penggunaannya:
Pengaturan waktu dibatasi oleh kecepatan algoritma cembung cembung, karena jumlah simpul dalam lambung hampir selalu jauh lebih sedikit daripada total. Sebagian besar algoritma cembung cangkang asimtotik O (n * log (n)) untuk n poin: Anda dapat menghitung hampir secepat Anda dapat membaca koordinat.
sumber
Saya baru saja mengimplementasikan ini sendiri dan memposting jawaban saya di StackOverflow , tetapi saya pikir saya akan menjatuhkan versi saya di sini agar orang lain dapat melihatnya:
Berikut ini empat contoh berbeda dalam aksi. Untuk setiap contoh, saya menghasilkan 4 poin acak dan menemukan kotak pembatas.
Ini juga relatif cepat untuk sampel-sampel ini pada 4 poin:
sumber
points = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
, dan hasilnya adalaharray([[1.00000000e+00, 6.12323400e-17], [0.00000000e+00, 0.00000000e+00], [6.12323400e-17, 1.00000000e+00], [1.00000000e+00, 1.00000000e+00]])
unit square itu sendiri (termasuk beberapa kesalahan pembulatan floating point). Catatan: persegi hanya persegi panjang dengan sisi yang sama, jadi saya berasumsi jika itu bisa menangani persegi itu digeneralisasi ke semua persegi panjang.Ada alat di Whitebox GAT ( http://www.uoguelph.ca/~hydrogeo/Whitebox/ ) yang disebut Kotak Batas Minimum untuk menyelesaikan masalah yang pasti ini. Ada juga alat lambung cembung minimum di sana juga. Beberapa alat dalam kotak Bentuk Patch, misalnya orientasi dan perpanjangan patch, didasarkan pada menemukan kotak batas minimum.
sumber
Saya menemukan utas ini sambil mencari solusi Python untuk persegi panjang batas minimum.
Inilah implementasi saya , yang hasilnya diverifikasi dengan Matlab.
Kode uji disertakan untuk poligon sederhana, dan saya menggunakannya untuk menemukan kotak batas minimum 2D dan arah sumbu untuk 3D PointCloud.
sumber
Terima kasih @ whuber. Ini adalah solusi yang bagus, tetapi lambat untuk cloud big point. Saya menemukan
convhulln
fungsi dalam paket Rgeometry
jauh lebih cepat (138 detik vs 0,03 detik untuk 200000 poin). Saya menempelkan kode saya di sini untuk siapa pun yang menarik untuk solusi yang lebih cepat.Dua metode mendapatkan jawaban yang sama (contoh untuk 2000 poin):
sumber
Saya hanya merekomendasikan fungsi built-in OpenCV
minAreaRect
, yang menemukan persegi panjang yang diputar dari area minimum yang melampirkan input set poin 2D. Untuk melihat bagaimana menggunakan fungsi ini, orang dapat merujuk ke tutorial ini .sumber