Supponiamo di avere 4 punti (sono bidimensionali), che sono diversi l'uno dall'altro, e voglio sapere se formano un quadrato. Come farlo? (lascia che il processo sia il più semplice possibile).
Supponiamo di avere 4 punti (sono bidimensionali), che sono diversi l'uno dall'altro, e voglio sapere se formano un quadrato. Come farlo? (lascia che il processo sia il più semplice possibile).
Risposte:
Supponendo che il tuo quadrato possa essere ruotato contro qualsiasi sistema di coordinate tu abbia in atto, non puoi fare affidamento sul fatto che ci sia una ripetizione dei valori X e Y nei tuoi quattro punti.
Quello che puoi fare è calcolare le distanze tra ciascuno dei quattro punti. Se ritieni che quanto segue sia vero, hai un quadrato:
Ci sono due punti, diciamo A e C che sono distanza x l' uno dall'altro, e altri due punti, dicono B e D che sono anche distanza x l' uno dall'altro.
Ogni punto {A, B, C, D} è uguale distanza dai due punti che non sono x di distanza. cioè: se A è x lontano da C, allora sarà z lontano sia da B che da D.
Per inciso, la distanza z dovrà essere SQRT (( x ^ 2) / 2), ma non è necessario confermarlo. Se le condizioni 1 e 2 sono vere, allora hai un quadrato. NOTA: alcune persone sono preoccupate per l'inefficienza della radice quadrata. Non ho detto che dovresti fare questo calcolo, ho solo detto che se lo facessi otterrai un risultato prevedibile!
Il minimo indispensabile di lavoro che dovresti fare sarebbe scegliere un punto, dire A e calcolare la distanza da ciascuno degli altri tre punti. Se riesci a trovare che A è x da un punto e z da altri due punti, devi solo controllare gli altri due punti uno contro l'altro. Se sono anche x l' uno dall'altro, allora hai un quadrato. vale a dire:
Da AB = AD, controlla BD:
Giusto per essere sicuri, è necessario controllare gli altri lati: BC e CD.
Poiché AC = BD e poiché AB = AD = BC = CD, questo è quindi un quadrato.
Lungo la strada, se trovi più di due distinte distanze dal bordo, la figura non può essere un quadrato, quindi puoi smettere di guardare.
Implementazione di esempio funzionante
Ho creato un esempio funzionante su jsfiddle (vedi qui ). Nella mia spiegazione dell'algoritmo, utilizzo i punti arbitrari A, B, C e D. Quei punti arbitrari si trovano in un certo ordine per il bene di percorrere l'esempio. L' algoritmo funziona anche se i punti sono in un ordine diverso, tuttavia l' esempio non funziona necessariamente se quei punti sono in un ordine diverso.
Grazie a: meshuai, Blrfl, MSalters e Bart van Ingen Schenau per commenti utili per migliorare questa risposta.
Scegli tre dei quattro punti.
Scopri se si tratta di un triangolo isoscele destro verificando se uno dei tre vettori tra i punti è uguale a un altro ruotato di 90 gradi.
In tal caso, calcola il quarto punto per addizione vettoriale e confrontalo con il quarto punto dato.
Si noti che ciò non richiede costose radici quadrate, nemmeno la moltiplicazione.
sqrt
se non cruciale! Non è necessario degradare i calcoli dei numeri interi in FP ... per non parlare del peggioramento della precisione del calcolo FP.
Penso che la soluzione più semplice sia la seguente:
Innanzitutto, calcola il centro dei 4 punti: center = (A + B + C + D)/4
Quindi calcola il vettore A - center
. Lascia che siav := (x,y)
Lascia che v2
il vettore sia v
ruotato di 90 gradi:v2 := (-y, x)
Ora gli altri punti dovrebbero essere center - v
, center + v2
e center - v2
.
Il vantaggio di questa soluzione è che non è necessario utilizzare le radici quadrate.
Mi dispiace ma alcune risposte non si applicano.
Nel caso in cui misuri 3 bordi (diciamo AB, AC e AD) per scoprire che due hanno le stesse dimensioni (diciamo AC e AD) e uno è più grande (diciamo AB). Quindi si misura il CD per vedere se ha le stesse dimensioni di AB e si scopre che lo è. Invece di un quadrato, potresti avere l'immagine qui sotto, e questo lo rende una soluzione sbagliata.
Quindi prova un'altra soluzione: misura tutte le distanze almeno una volta: AB, AC, AD, BC, BD, CD. Quindi scopri che 4 di questi sono uguali e anche gli altri 2 sono uguali tra loro. Ma potresti semplicemente avere una foto come di seguito:
Quindi, quelle risposte non sono corrette, nonostante gli alti voti che hanno ricevuto.
Una possibile soluzione: se le due misure uguali non collegano lo stesso punto. Quindi: se AB e CD hanno la stessa lunghezza, tutte le altre combinazioni (AC, AD, BC, BD) sono uguali, hai un quadrato. Se hai lo stesso punto facendo la lunghezza maggiore (AB e AC sono le più grandi, e tutte le altre sono uguali), hai una delle immagini sopra.
Lascia che i quattro punti abbiano coordinate vettoriali a, b, c, d.
Quindi consente di chiamare le loro differenze w = (annuncio), x = (ba), y = (cb), z = (dc).
Quindi w è ortogonale a a se è possibile creare w da a con una rotazione di 90 gradi. Matematicamente la matrice di rotazione di 90 gradi nello spazio 2 è ((0, -1), (1, 0)). Pertanto, risulta la condizione se w sia ruotato di 90 gradi
(w_1 == -x_2 e w_2 == x_1)
Se questo vale, allora devi controllare che w == -y e x == -z, o
((w_1 == -y_1 e w_2 == -y_2) e (x_1 == -z_1 e x_2 == -z_2))
Se queste tre relazioni sono valide, a, b, c, d formano un quadrato orientato.
Simile alla risposta di starblue
Scegli tre dei quattro punti.
Cerca tra loro un vertice ad angolo retto : controllando se il prodotto punto di uno dei due vettori è zero. Se non trovato, non un quadrato.
Controlla se anche i vertici adiacenti a questo angolo sono ad angolo retto. Altrimenti, non un quadrato.
Verifica se le diagonali sono perpendicolari : se il prodotto punto dei vettori tra il primo e il quarto vertice e gli altri due vertici (diagonali) è zero, allora è un quadrato.
Penso che puoi farlo con semplice aggiunta e sottrazione e trovare min / max. Termini (corrisponde al diagramma di altre persone):
Se 4 punti condividono solo 2 valori x e 2 valori y hai un quadrato di livello.
Altrimenti, hai un quadrato se i tuoi punti soddisfano quanto segue:
Spiegazione: I segmenti di linea AC e BD devono incontrarsi ai loro punti medi. Pertanto (Ax + Cx) / 2 è il punto medio di AC e (Bx + Dx) / 2 è il punto medio di BD. Moltiplica ogni lato di questa equazione per 2 per ottenere la mia prima equazione. La seconda equazione è la stessa cosa per i valori Y. Le forme a diamante (romboidi) soddisferanno queste proprietà, quindi è necessario verificare di avere lati uguali - che la larghezza sia uguale all'altezza. Questa è la terza equazione.
Ci sono alcune buone risposte qui, ma la domanda ha richiesto l'approccio più semplice. Ci ho pensato in fretta ed è così che lo farei.
Puoi stabilire se quattro punti rappresentano un quadrato (anche se ruotato), ma trova la media dei quattro punti.
R = (A+B+C+D)/4
Una volta ottenuta la media, la distanza tra ciascun punto e la media dovrebbe essere la stessa per tutti e quattro i punti.
if(dist(R,A) == dist(R,B) == dist(R,C) == dist(R,D) then
print "Is Square"
else
print "Is Not Square"
MODIFICARE:
Errore mio. Ciò ti direbbe solo se i punti del modulo fossero su un cerchio. Se controlli anche la distanza tra i punti, allora deve essere un quadrato.
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"
Ciò presuppone che i punti A, B, C, D non attraversino (poiché in un ordine di avvolgimento valido).
questa non è una risposta secondo gli standard stabiliti, ma spero che questo aiuti:
[Copiato dal link sottostante in modo da non dover aprire il link] Python 76 caratteri
def S(A):c=sum(A)/4.0;return set(A)==set((A[0]-c)*1j**i+c for i in range(4))
La funzione S prende un elenco di numeri complessi come input (A). Se conosciamo sia il centro che un angolo di un quadrato, possiamo ricostruire il quadrato ruotando l'angolo di 90.180 e 270 gradi attorno al punto centrale (c). Sul piano complesso la rotazione di 90 gradi attorno all'origine viene eseguita moltiplicando il punto per i. Se la nostra forma originale e il quadrato ricostruito hanno gli stessi punti, allora deve essere stato un quadrato.
Questo è stato preso da: Determina se 4 punti formano un quadrato
Se ti piace la risposta, dico, prenditi qualche momento per ringraziare la persona, o vota la sua risposta su quella pagina.
Idea di base (questo risponde alla domanda se stavo contribuendo con qualcosa di nuovo, che mi è stato chiesto dal bot quando ho cliccato per fornire una risposta):
La mia soluzione in R è presentata di seguito. Sto assumendo che ci siano esattamente quattro punti e che, per l'affermazione del problema, è già stato stabilito che i punti sono unici.
sumsq <- function(x) sum(x^2)
quadrances.xy <- function(xy) vapply(
as.data.frame(t(diff(xy)), optional=T), sumsq, 1)
Guarda le opere di Norman Wildberger, in particolare i suoi video su YouTube ( Pesce reale, numeri reali, posti di lavoro reali e seguenti) e il suo libro Divine Proportions per una discussione sul "quadrance".
xy
si riferisce ad un tipo di matrice di accettato da R plot
, points
e lines
funzioni.
L'applicazione di as.data.frame
è un trucco per convincere R a fare le cose per colonne.
La optional=T
clausola elimina comunque i nomi che non vengono utilizzati.
quadrances.xy..i2. <- function(xy, i2) vapply(
as.data.frame(i2, optional=T),
function(k) quadrances.xy(m[k,]),
1)
Questa è una funzione per calcolare i quadranti tra i punti specificati, dove coppie di punti sono specificate i2
dall'argomento. Il i2
simbolo si riferisce a una matrice di indice che ha una colonna per indice e 2 elementi per colonna (lo stesso tipo di matrice restituita dalla combn
funzione).
quadrance.every.xy <- function(xy, .which=combn(nrow(xy), 2))
quadrances.xy..i2.(xy, .which)
Il .which
è presentato come un argomento solo per esporla alla formals
e tentare di comunicare ciò che sta succedendo.
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
}
Ho detto che "semplice" non includeva funzioni multilinea. Dovrai scusare questa funzione a due righe.
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
Si noti che le prime quattro funzioni sono utili di per sé, a parte la domanda sui quattro punti.
Assumi quattro punti A = (ax, ay), B = (bx, by), C = (cx, cy), D = (dx, dy) e formano i punti di un quadrato in ordine antiorario. Spostiamo i punti in modo che A sia a (0, 0) sottraendo ax da bx, cx e dx e sottraendo ay da da, cy e dy, impostando ax = ay = 0.
Se i punti sono esattamente gli angoli di un quadrato in ordine antiorario, quindi dati A e B, possiamo calcolare dove sono C e D: dovremmo avere (cx, cy) = (bx - by, bx + by) e (dx, dy) = (-by, bx). Quindi calcoliamo la distanza quadrata da dove si trovano C e D, dove dovrebbero essere: errC = (cx - bx + di) ^ 2 + (cy - bx - by) ^ 2, ed errD = (dx + by) ^ 2 + (dy - bx) ^ 2. Aggiungiamo questi e dividiamo per (bx ^ 2 + per ^ 2), dando err = (errC + errD) / (bx ^ 2 + per ^ 2).
Il risultato err sarebbe 0 se un quadrato perfetto, o un piccolo numero se quasi un quadrato, e il numero rimarrebbe invariato tranne gli errori di arrotondamento se traduciamo, ridimensioniamo o ruotiamo i punti del quadrato. Quindi possiamo usare err per decidere quanto è buono un quadrato.
Ma non conosciamo l'ordinamento dei punti. B e D dovrebbero essere alla stessa distanza da A; se moltiplichiamo questo per la radice quadrata di 2, quella dovrebbe essere la distanza da A a C. Usiamo questo per capire quale punto è C: Calcola distB = bx ^ 2 + per ^ 2, distD = dx ^ 2 + dy ^ 2. Se distD ≥ 1,5 distB, scambiamo C e D; se distB ≥ 1,5 distD scambiamo C e B. Ora C ha ragione.
Possiamo anche capire quali punti sono B e D: se abbiamo indovinato quale sia B e quale sia D, allora il nostro calcolo pone D nel posto completamente sbagliato, esattamente opposto a dove si trova. Quindi se errD ≥ (bx ^ 2 + per ^ 2), allora scambiamo B e D.
Questo sistemerà B, C e D correttamente se abbiamo davvero un quadrato o almeno approssimativamente un quadrato. Ma se non abbiamo nemmeno un quadrato, sappiamo che il calcolo dell'errore alla fine lo mostrerà.
Sommario:
Se conosciamo l'ordine dei punti, questo può ovviamente essere semplificato.
La soluzione è simile al pensiero mediatico.
Primo passo:
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
Questa proprietà è seguita da quadrato perché è ciclico. ora un cerchio per seguire questa proprietà. quindi, ora basta controllare
if(A.B==B.C==C.D==D.A==0)
f=1
else
f=0
if (f==1)
square
else
not square
Qui AB significa punto prodotto di A e B