Giả sử tôi có 4 điểm (chúng là 2 chiều), khác nhau và tôi muốn biết liệu chúng có tạo thành hình vuông không. Làm thế nào để làm nó? (hãy để quá trình này đơn giản nhất có thể.)
Giả sử tôi có 4 điểm (chúng là 2 chiều), khác nhau và tôi muốn biết liệu chúng có tạo thành hình vuông không. Làm thế nào để làm nó? (hãy để quá trình này đơn giản nhất có thể.)
Câu trả lời:
Giả sử rằng hình vuông của bạn có thể được xoay theo bất kỳ hệ tọa độ nào bạn có, bạn không thể dựa vào việc có bất kỳ sự lặp lại nào của các giá trị X và Y trong bốn điểm của bạn.
Những gì bạn có thể làm là tính khoảng cách giữa mỗi bốn điểm. Nếu bạn thấy những điều sau đây là đúng, bạn có một hình vuông:
Có hai điểm, giả sử A và C là khoảng cách x với nhau và hai điểm khác, nói B và D cũng là khoảng cách x với nhau.
Mỗi điểm {A, B, C, D} là một khoảng cách bằng nhau từ hai điểm không x đi. ví dụ: Nếu A là x đi từ C, sau đó nó sẽ được z xa cả B và D.
Ngẫu nhiên, khoảng cách z sẽ phải là SQRT (( x ^ 2) / 2), nhưng bạn không cần phải xác nhận điều này. Nếu điều kiện 1 và 2 là đúng thì bạn có hình vuông. LƯU Ý: Một số người lo ngại về sự kém hiệu quả của căn bậc hai. Tôi không nói rằng bạn nên thực hiện phép tính này, tôi chỉ nói rằng nếu bạn làm bạn sẽ nhận được một kết quả có thể dự đoán được!
Công việc tối thiểu mà bạn cần làm sẽ là chọn một điểm, nói A và tính khoảng cách đến ba điểm còn lại. Nếu bạn có thể thấy rằng A là x từ một điểm và z từ hai điểm khác, thì bạn chỉ cần kiểm tra hai điểm khác đó với nhau. Nếu chúng cũng x cách nhau thì bạn có hình vuông. I E:
Vì AB = AD, kiểm tra BD:
Để chắc chắn, bạn cần kiểm tra các mặt khác: BC và CD.
Vì AC = BD và vì AB = AD = BC = CD, do đó đây là một hình vuông.
Trên đường đi, nếu bạn tìm thấy nhiều hơn hai khoảng cách cạnh khác nhau thì hình không thể là hình vuông, vì vậy bạn có thể ngừng tìm kiếm.
Thực hiện ví dụ làm việc
Tôi đã tạo một ví dụ hoạt động trên jsfiddle (xem tại đây ). Trong phần giải thích của tôi về thuật toán, tôi sử dụng các điểm A, B, C và D. tùy ý, các điểm tùy ý đó xảy ra theo một thứ tự nhất định để đi qua ví dụ. Các thuật toán làm việc ngay cả nếu các điểm đang ở trong một thứ tự khác nhau, tuy nhiên, ví dụ không nhất thiết phải làm việc nếu những điểm nằm trong một trật tự khác nhau.
Cảm ơn: lướiuai, Blrfl, MSalters và Bart van Ingen Schenau vì những bình luận hữu ích để cải thiện câu trả lời này.
Chọn ba trong bốn điểm.
Tìm hiểu xem đó có phải là tam giác cân bằng cách kiểm tra xem một trong ba vectơ giữa các điểm có bằng một vectơ khác xoay 90 độ không.
Nếu vậy, hãy tính điểm thứ tư bằng phép cộng vector và so sánh với điểm thứ tư đã cho.
Lưu ý rằng điều này không đòi hỏi căn bậc hai đắt tiền, thậm chí không nhân.
sqrt
trừ khi rất quan trọng! Bạn không cần phải làm giảm các phép tính số nguyên xuống FP ... chưa kể đến việc làm giảm độ chính xác của tính toán FP.
Tôi nghĩ giải pháp đơn giản nhất là như sau:
Đầu tiên, tính trung tâm của 4 điểm: center = (A + B + C + D)/4
Sau đó tính toán vectơ A - center
. Để nóv := (x,y)
Gọi v2
là vectơ v
xoay 90 độ:v2 := (-y, x)
Bây giờ các điểm khác nên center - v
, center + v2
và center - v2
.
Ưu điểm của giải pháp này là bạn hoàn toàn không phải sử dụng căn bậc hai.
Tôi xin lỗi nhưng một số câu trả lời không áp dụng.
Đối với trường hợp bạn đo 3 cạnh (giả sử AB, AC và AD) để thấy rằng hai cạnh có cùng kích thước (giả sử AC và AD) và một cạnh lớn hơn (giả sử AB). Sau đó, bạn sẽ đo CD để xem nó có cùng kích cỡ AB hay không và bạn thấy rằng đó là. Thay vì hình vuông, bạn có thể có hình dưới đây, và điều đó làm cho nó trở thành một giải pháp sai.
Sau đó, bạn thử một số giải pháp khác: đo tất cả các khoảng cách ít nhất một lần: AB, AC, AD, BC, BD, CD. Sau đó, bạn thấy rằng 4 trong số đó là bằng nhau và 2 người còn lại cũng bằng nhau. Nhưng bạn chỉ có thể có một hình ảnh như dưới đây:
Vì vậy, những câu trả lời đó không chính xác, mặc dù họ đã nhận được rất nhiều lượt ủng hộ.
Một giải pháp khả thi: nếu hai biện pháp bằng nhau không kết nối cùng một điểm. Vì vậy: nếu AB và CD có cùng chiều dài, tất cả các kết hợp khác (AC, AD, BC, BD) cũng bằng nhau, bạn có một hình vuông. Nếu bạn có cùng một điểm làm cho độ dài lớn nhất (AB và AC là lớn nhất và tất cả các điểm khác đều bằng nhau), bạn có một trong các hình trên.
Cho bốn điểm có vectơ tọa độ a, b, c, d.
Sau đó, hãy gọi sự khác biệt của họ w = (quảng cáo), x = (ba), y = (cb), z = (dc).
Sau đó, w là trực giao với a nếu bạn có thể tạo w từ một góc quay 90 độ. Về mặt toán học, ma trận xoay 90 độ trong 2 không gian là ((0, -1), (1, 0)). Do đó, điều kiện cho dù w là xoay 90 độ, kết quả là
(w_1 == -x_2 và w_2 == x_1)
Nếu cái này giữ, thì bạn cần kiểm tra xem w == -y và x == -z, hay
((w_1 == -y_1 và w_2 == -y_2) và (x_1 == -z_1 và x_2 == -z_2))
Nếu ba quan hệ đó giữ, a, b, c, d tạo thành một hình vuông có định hướng.
Tương tự như câu trả lời của starblue
Chọn bất kỳ ba trong bốn điểm.
Tìm một đỉnh góc phải trong số chúng : Bằng cách kiểm tra xem sản phẩm chấm của bất kỳ hai trong ba vectơ có bằng không. Nếu không tìm thấy, không phải là một hình vuông.
Kiểm tra xem các đỉnh liền kề với góc này có đúng không. Nếu không, không phải là một hình vuông.
Kiểm tra xem các đường chéo có vuông góc hay không : Nếu tích của các vectơ giữa đỉnh thứ nhất và thứ tư và hai đỉnh còn lại (đường chéo) bằng 0, thì đó là một hình vuông.
Tôi nghĩ bạn có thể làm điều này với phép cộng và phép trừ đơn giản và tìm min / max. Điều khoản (khớp với sơ đồ của người khác):
Nếu 4 điểm chỉ chia sẻ 2 giá trị x và 2 giá trị y thì bạn có bình phương cấp.
Mặt khác, bạn có một hình vuông nếu điểm của bạn thỏa mãn những điều sau:
Giải thích: Các đoạn thẳng AC và BD sẽ gặp nhau tại điểm giữa của chúng. Do đó (Ax + Cx) / 2 là trung điểm của AC và (Bx + Dx) / 2 là trung điểm của BD. Nhân mỗi bên của phương trình này với 2 để có phương trình đầu tiên của tôi. Phương trình thứ hai là điều tương tự cho các giá trị Y. Hình dạng kim cương (rhomboids) sẽ đáp ứng các tính chất này, vì vậy bạn cần kiểm tra xem bạn có các cạnh bằng nhau không - chiều rộng có giống với chiều cao không. Đó là phương trình thứ ba.
Có một số câu trả lời tốt ở đây, nhưng câu hỏi yêu cầu cách tiếp cận đơn giản nhất. Tôi đã suy nghĩ nhanh và đây là cách tôi sẽ làm.
Bạn có thể biết nếu bốn điểm đại diện cho một hình vuông (ngay cả khi xoay), nhưng tìm trung bình của bốn điểm.
R = (A+B+C+D)/4
Khi bạn có điểm trung bình, khoảng cách giữa mỗi điểm và điểm trung bình sẽ phải giống nhau cho cả bốn điểm.
if(dist(R,A) == dist(R,B) == dist(R,C) == dist(R,D) then
print "Is Square"
else
print "Is Not Square"
CHỈNH SỬA:
Lỗi của tôi. Điều đó sẽ chỉ cho bạn biết nếu các điểm hình thức nằm trên một vòng tròn. Nếu bạn cũng kiểm tra khoảng cách giữa các điểm, thì đó phải là một hình vuông.
if(dist(R,A) == dist(R,B) == dist(R,C) == dist(R,D) AND
(dist(A,B) == dist(B,C) == dist(C,D) == dist(A,D) then
print "Is Square"
else
print "Is Not Square"
Điều này giả định rằng các điểm A, B, C, D không giao nhau (như trong lệnh có cuộn dây hợp lệ).
Đây không phải là một câu trả lời theo các tiêu chuẩn được đặt ra, nhưng tôi hy vọng điều này sẽ giúp:
[Sao chép từ liên kết bên dưới để bạn không phải mở liên kết] Python 76 ký tự
def S(A):c=sum(A)/4.0;return set(A)==set((A[0]-c)*1j**i+c for i in range(4))
Hàm S lấy danh sách các số phức làm đầu vào (A). Nếu chúng ta biết cả tâm và một góc của hình vuông, chúng ta có thể xây dựng lại hình vuông bằng cách xoay góc 90.180 và 270 độ quanh điểm trung tâm (c). Trên mặt phẳng phức quay 90 độ về gốc tọa độ được thực hiện bằng cách nhân điểm với i. Nếu hình dạng ban đầu của chúng ta và hình vuông được xây dựng lại có cùng một điểm thì nó phải là một hình vuông.
Điều này được lấy từ: Xác định nếu 4 điểm tạo thành một hình vuông
Nếu bạn thích câu trả lời, tôi nói, hãy dành một chút thời gian để cảm ơn người đó, hoặc bỏ phiếu cho câu trả lời của anh ấy trên trang đó.
Ý tưởng cơ bản (điều này trả lời câu hỏi liệu tôi có đóng góp gì mới không, được bot hỏi khi tôi nhấp để cung cấp câu trả lời):
Giải pháp của tôi trong R được trình bày dưới đây. Tôi giả định rằng có chính xác bốn điểm và theo tuyên bố vấn đề, đã xác định rằng các điểm là duy nhất.
sumsq <- function(x) sum(x^2)
quadrances.xy <- function(xy) vapply(
as.data.frame(t(diff(xy)), optional=T), sumsq, 1)
Xem các tác phẩm của Norman Wildberger, đặc biệt là các video trên YouTube của anh ấy ( Cá thật, số thực, công việc thực và công việc ) và cuốn sách Tỷ lệ thiêng liêng của anh ấy để thảo luận về "tứ giác".
xy
đề cập đến một loại ma trận được chấp nhận bởi R của plot
, points
và lines
chức năng.
Áp dụng as.data.frame
là một mẹo để khiến R thực hiện những điều khôn ngoan.
Các optional=T
điều khoản loại trừ tên, mà không được sử dụng, dù sao.
quadrances.xy..i2. <- function(xy, i2) vapply(
as.data.frame(i2, optional=T),
function(k) quadrances.xy(m[k,]),
1)
Đây là một hàm để tính các góc phần giữa các điểm được chỉ định, trong đó các cặp điểm được chỉ định bởi i2
đối số. Các i2
biểu tượng dùng để chỉ một ma trận chỉ số trong đó có một cột cho mỗi chỉ số, và 2 yếu tố cho mỗi cột (cùng một loại ma trận được trả về bởi các combn
chức năng).
quadrance.every.xy <- function(xy, .which=combn(nrow(xy), 2))
quadrances.xy..i2.(xy, .which)
Điều .which
này được trình bày như là một đối số chỉ để phơi bày nó formals
và cố gắng truyền đạt những gì đang diễn ra.
is.square.xy <- function(xy) {
qq <- sort(quadrance.every.xy(xy))
all(qq[2:4] == qq[1]) && # ALL SIDES (SHORT QUADRANCES) EQUAL
qq[5] == qq[6] # ALL DIAGONALS (LONG QUADRANCES) EQUAL
}
Tôi nói "đơn giản" không bao gồm các chức năng đa dòng. Bạn sẽ phải bào chữa cho chức năng hai dòng này.
xy <- t(matrix(c(3,0, 7,3, 4,7, 0,4), ncol=4))
xy
# [,1] [,2]
# [1,] 3 0
# [2,] 7 3
# [3,] 4 7
# [4,] 0 4
is.square.xy(xy)
# [1] TRUE
Lưu ý rằng bốn chức năng đầu tiên là hữu ích theo cách riêng của họ, ngoài câu hỏi về bốn điểm.
Giả sử bốn điểm A = (ax, ay), B = (bx, by), C = (cx, cy), D = (dx, dy) và chúng tạo thành các điểm của hình vuông theo thứ tự ngược chiều kim đồng hồ. Chúng ta di chuyển các điểm sao cho A ở (0, 0) bằng cách trừ ax ra khỏi bx, cx và dx và trừ ay từ, cy và dy, đặt ax = ay = 0.
Nếu các điểm chính xác là các góc của hình vuông theo thứ tự ngược chiều kim đồng hồ, thì được cho A và B, chúng ta có thể tính được C và D ở đâu: Chúng ta nên có (cx, cy) = (bx - by, bx + by) và (dx, dy) = (-by, bx). Vì vậy, chúng tôi tính khoảng cách bình phương từ vị trí của C và D, đến vị trí của chúng: errC = (cx - bx + by) ^ 2 + (cy - bx - by) ^ 2 và errD = (dx + by) ^ 2 + (dy - bx) ^ 2. Chúng tôi thêm chúng và chia cho (bx ^ 2 + cho ^ 2), đưa ra err = (errC + errD) / (bx ^ 2 + by ^ 2).
Sai số kết quả sẽ là 0 nếu một hình vuông hoàn hảo hoặc một số nhỏ nếu gần như một hình vuông và con số sẽ không thay đổi trừ các lỗi làm tròn nếu chúng ta dịch, chia tỷ lệ hoặc xoay các điểm của hình vuông. Vì vậy, chúng ta có thể sử dụng err để quyết định xem chúng ta có hình vuông tốt như thế nào.
Nhưng chúng tôi không biết thứ tự của các điểm. B và D nên ở cùng khoảng cách với A; nếu chúng ta nhân số này với căn bậc hai của 2, thì đó sẽ là khoảng cách từ A đến C. Chúng tôi sử dụng điểm này để tìm ra điểm nào là C: Tính distB = bx ^ 2 + cho ^ 2, distD = dx ^ 2 + dy ^ 2. Nếu distD ≥ 1,5 distB, thì chúng ta trao đổi C và D; nếu distB ≥ 1,5 distD thì ta trao đổi C và B. Bây giờ C đã đúng.
Chúng ta cũng có thể tìm ra điểm nào là B và D: Nếu chúng ta đoán sai điểm nào là B và điểm nào là D, thì phép tính của chúng ta đặt D vào vị trí hoàn toàn sai, hoàn toàn ngược lại với vị trí của nó. Vì vậy, nếu errD (bx ^ 2 + by ^ 2), thì chúng ta trao đổi B và D.
Điều này sẽ sắp xếp B, C và D chính xác nếu chúng ta có một hình vuông thực sự hoặc ít nhất là khoảng một hình vuông. Nhưng nếu chúng ta thậm chí không có khoảng một hình vuông, chúng ta biết tính toán lỗi ở cuối sẽ hiển thị điều này.
Tóm lược:
Nếu chúng ta biết thứ tự của các điểm, điều này rõ ràng có thể được đơn giản hóa.
Giải pháp tương tự như tư duy truyền thông.
Bước đầu tiên:
x = (A+B+C+D)/4
f=0
if(dist(x,A) == dist(x,B) == dist(x,C) == dist(x,D)
f=1
else
f=0
Tài sản này được theo sau bởi hình vuông vì nó là chu kỳ. bây giờ một vòng tròn để theo tài sản này. vì vậy, bây giờ chỉ cần kiểm tra
if(A.B==B.C==C.D==D.A==0)
f=1
else
f=0
if (f==1)
square
else
not square
Ở đây AB có nghĩa là sản phẩm chấm của A và B