Припустимо, у мене є 4 точки (вони двовимірні), які відрізняються один від одного, і я хочу знати, чи утворюють вони квадрат. Як це зробити? (нехай процес буде максимально простим.)
Припустимо, у мене є 4 точки (вони двовимірні), які відрізняються один від одного, і я хочу знати, чи утворюють вони квадрат. Як це зробити? (нехай процес буде максимально простим.)
Відповіді:
Якщо припустити, що ваш квадрат може бути повернутий проти будь-якої системи координат у вас є, ви не можете розраховувати на те, що у ваших чотирьох точках буде повторення значень X і Y.
Що ви можете зробити, це обчислити відстані між кожною з чотирьох точок. Якщо ви вважаєте, що це правда, у вас є квадрат:
Є дві точки, скажімо, A і C, які відстані x одна від одної, і дві інші точки, скажімо B і D, які також відстань x одна від одної.
Кожна точка {A, B, C, D} - це однакова відстань від двох точок, які не відходять x . тобто: Якщо A знаходиться на відстані x від С, то він буде від z і від B, і від D.
Між іншим, відстань z повинна бути SQRT (( x ^ 2) / 2), але вам це не потрібно підтверджувати. Якщо умови 1 і 2 вірні, то у вас квадрат. ПРИМІТКА. Деякі люди стурбовані неефективністю квадратного кореня. Я не казав, що ви повинні робити цей розрахунок, я просто сказав, що якщо ви це зробите, ви отримаєте передбачуваний результат!
Голим мінімумом роботи, який вам потрібно буде зробити, було б вибрати точку, скажімо, A і обчислити відстань до кожної з трьох інших точок. Якщо ви можете виявити, що A є x від однієї точки, а z від двох інших точок, тоді вам потрібно просто перевірити ці дві інші точки один проти одного. Якщо вони також х один від одного, то у вас є квадрат. тобто:
Оскільки AB = AD, перевірте BD:
Щоб переконатися, вам потрібно перевірити інші сторони: BC та CD.
Оскільки AC = BD і оскільки AB = AD = BC = CD, то це квадрат.
Попутно, якщо ви знайдете більше двох чітких крайових відстаней, то фігура не може бути квадратною, тому ви можете перестати шукати.
Реалізація робочого прикладу
Я створив робочий приклад на jsfiddle (див. Тут ). У своєму поясненні алгоритму я використовую довільні точки A, B, C та D. Ці довільні точки трапляються у певному порядку заради проходження прикладу. Алгоритм працює , навіть якщо точки знаходяться в іншому порядку, однак, приклад не обов'язково працювати , якщо ці точки знаходяться в іншому порядку.
Дякуємо: meshuai, Blrfl, MSalters та Bart van Ingen Schenau за корисні коментарі для покращення цієї відповіді.
Виберіть три з чотирьох пунктів.
З'ясуйте, чи це правильний рівнобедрений трикутник, перевіривши, чи один з трьох векторів між точками дорівнює іншому, повернутий на 90 градусів.
Якщо так, обчисліть четверту точку шляхом додавання вектора та порівняйте її із заданою четвертою точкою.
Зауважте, що для цього не потрібні дорогі квадратні корені, навіть не множення.
sqrt
якщо не вирішальне значення! Вам не потрібно деградувати цілочисельні обчислення до FP ... не кажучи вже про погіршення точності обчислення FP.
Я думаю, що найпростішим рішенням є наступне:
Спочатку обчисліть центр 4-х балів: center = (A + B + C + D)/4
Потім обчисліть вектор A - center
. Нехай це будеv := (x,y)
Нехай v2
вектор v
повертається на 90 градусів:v2 := (-y, x)
Тепер інші пункти повинні бути center - v
, center + v2
і center - v2
.
Перевага цього рішення полягає в тому, що вам зовсім не доведеться використовувати квадратні корені.
Вибачте, але деякі відповіді не застосовуються.
У випадку, коли ви вимірюєте 3 ребра (скажімо, AB, AC і AD), виявите, що два мають однаковий розмір (скажімо, AC і AD), а один - більший (скажімо, AB). Тоді ви б виміряли компакт-диск, щоб побачити, чи є він однакового розміру AB, і ви виявите, що він є. Замість квадрата ви можете мати малюнок нижче, і це робить його неправильним рішенням.
Тоді ви спробуйте якесь інше рішення: хоча б раз виміряйте всі відстані: AB, AC, AD, BC, BD, CD. Тоді ви виявляєте, що 4 тоді рівні, а інші 2 також рівні між собою. Але ви могли просто мати малюнок, як показано нижче:
Отже, ці відповіді невірні, незважаючи на високі результати, які вони отримали.
Одне можливе рішення: якщо два рівні заходи не з'єднають одну і ту ж точку. Отже: якщо AB і CD однакові по довжині, всі інші комбінації (AC, AD, BC, BD) також рівні, у вас квадрат. Якщо у вас однакова точка, яка робить найбільшу довжину (AB і AC є найбільшою, а всі інші рівні), у вас є одне із зображень, наведених вище.
Нехай чотири точки мають вектори координат a, b, c, d.
Тоді давайте назвемо їх різниці w = (ad), x = (ba), y = (cb), z = (dc).
Тоді w є ортогональним до a, якщо ви можете створити w за допомогою обертання на 90 градусів. Математично матриця обертання на 90 градусів у 2-просторі дорівнює ((0, -1), (1, 0)). Таким чином, умова, чи w - повернутий на 90 градусів, призводить до
(w_1 == -x_2 та w_2 == x_1)
Якщо це має місце, то вам потрібно перевірити, що w == -y і x == -z, або
((w_1 == -y_1 і w_2 == -y_2) і (x_1 == -z_1 і x_2 == -z_2))
Якщо ці три відношення дотримуються, a, b, c, d складають орієнтований квадрат.
Схожий на відповідь від starblue
Виберіть будь-які три з чотирьох пунктів.
Шукайте серед них праву кутову вершину : Перевіряючи, чи крапковий добуток будь-якого з трьох векторів дорівнює нулю. Якщо не знайдено, не квадрат.
Перевірте, чи вершини, що прилягають до цього кута, теж під кутом. Якщо ні, не квадрат.
Перевірте, чи діагоналі перпендикулярні : Якщо крапковий добуток векторів між першою та четвертою вершиною та двома іншими вершинами (діагоналями) дорівнює нулю, то його квадрат.
Я думаю, ви можете зробити це простим додаванням і відніманням і знаходженням min / max. Умови (відповідає схемі інших людей):
Якщо 4 бали поділяють лише 2 x значення та 2 y значення, у вас є рівень рівня.
В іншому випадку у вас є квадрат, якщо ваші точки задовольняють наступному:
Пояснення: відрізки рядків AC та BD повинні зустрічатися в їх середині. Таким чином (Ax + Cx) / 2 є серединою точки змінного струму, а (Bx + Dx) / 2 - серединою точки BD. Помножте кожну сторону цього рівняння на 2, щоб отримати моє перше рівняння. Друге рівняння - те саме, що і для значень Y. Діамантові форми (ромбовиди) задовольнять ці властивості, тому вам потрібно перевірити, чи немає у вас рівних сторін - чи ширина така ж, як і висота. Це третє рівняння.
Тут є кілька хороших відповідей, але питання задало найпростіший підхід. Я дав цьому короткий роздум і ось як би це зробив.
Ви можете сказати, чи чотири точки представляють квадрат (навіть якщо він повернутий), але знаходячи середнє значення чотирьох точок.
R = (A+B+C+D)/4
Після того, як у вас буде середнє значення, відстань між кожною точкою та середнім значенням має бути однаковим для всіх чотирьох балів.
if(dist(R,A) == dist(R,B) == dist(R,C) == dist(R,D) then
print "Is Square"
else
print "Is Not Square"
Редагувати:
Моя помилка. Це скаже вам лише, якщо точки форми були на колі. Якщо ви також перевіряєте відстань між точками, то це має бути квадрат.
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"
Це передбачає, що точки A, B, C, D не перетинаються (як у дійсному порядку намотування).
це не відповідь відповідно до встановлених стандартів, але я сподіваюся, що це допомагає:
[Скопійовано із посилання нижче, так що вам не доведеться відкривати посилання] Python 76 символів
def S(A):c=sum(A)/4.0;return set(A)==set((A[0]-c)*1j**i+c for i in range(4))
Функція S приймає список складних чисел як свій вхід (A). Якщо ми знаємо і центр, і один кут квадрата, ми можемо реконструювати квадрат, обертаючи кут на 90,180 та 270 градусів навколо центральної точки (с). На складній площині обертання на 90 градусів щодо початку відбувається шляхом множення точки на i. Якщо наша первісна форма і реконструйований квадрат мають однакові точки, то це, мабуть, був квадрат.
Це було взято з: Визначте, чи 4 точки утворюють квадрат
Якщо вам подобається відповідь, я кажу, подякуйте людині, або голосуйте за його відповідь на цій сторінці.
Основна ідея (це відповідає на питання, чи я вносив щось нове, про що бот запитав, коли натиснув, щоб надати відповідь):
Моє рішення в R представлено нижче. Я припускаю, що рівно чотири пункти, і що, згідно з постановкою проблеми, вже було визначено, що бали є унікальними.
sumsq <- function(x) sum(x^2)
quadrances.xy <- function(xy) vapply(
as.data.frame(t(diff(xy)), optional=T), sumsq, 1)
Дивіться твори Нормана Уайлдбергера, особливо його відео на YouTube ( Справжня риба, реальні цифри, реальні роботи тощо) та його книгу Божественні пропорції для обговорення "квадрації".
xy
ставиться до свого роду матриця , прийнятої R в plot
, points
і lines
функції.
Застосування as.data.frame
- це хитрість, щоб змусити R робити речі в стовпцях.
optional=T
Положення виключає імена, які не використовуються, у всякому разі.
quadrances.xy..i2. <- function(xy, i2) vapply(
as.data.frame(i2, optional=T),
function(k) quadrances.xy(m[k,]),
1)
Це функція для обчислення квадрантів між зазначеними точками, де парами точок задаються i2
аргументом. i2
Символ відноситься до матриці індексу , який має один стовпець , індекс, і 2 елементів на колонці (такий же вигляд матриці , повернене combn
функцією).
quadrance.every.xy <- function(xy, .which=combn(nrow(xy), 2))
quadrances.xy..i2.(xy, .which)
.which
Представлений в якості аргументу просто виставити його formals
і спробувати передати те , що відбувається.
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
}
Я сказав, що "простий" не включав багаторядкових функцій. Вам доведеться вибачити цю дворядкову функцію.
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
Зауважте, що перші чотири функції корисні самі по собі, крім питання про чотири моменти.
Припустимо чотири точки A = (ax, ay), B = (bx, by), C = (cx, cy), D = (dx, dy), і вони утворюють точки квадрата в упорядкуванні проти годинникової стрілки. Переміщаємо точки так, що A знаходиться в (0, 0), віднімаючи ось від bx, cx і dx, і віднімаючи ay від, cy, і dy, задаючи ax = ay = 0.
Якщо точки - це саме кути квадрата в упорядкуванні проти годинникової стрілки, то, задавши A і B, ми можемо обчислити, де C і D: Ми повинні мати (cx, cy) = (bx - by, bx + by) і (dx, dy) = (-by, bx). Отже, ми обчислюємо відстань у квадраті від місця, де знаходяться C і D, до місця, де вони повинні бути: errC = (cx - bx + by) ^ 2 + (cy - bx - by) ^ 2, і errD = (dx + by) ^ 2 + (dy - bx) ^ 2. Додаємо ці і ділимо на (bx ^ 2 + на ^ 2), даючи err = (errC + errD) / (bx ^ 2 + на ^ 2).
Помилка результату буде 0, якщо досконалий квадрат, або невелике число, якщо майже квадрат, і число залишатиметься незмінним, за винятком помилок округлення, якщо ми переводимо, масштабуємо або обертаємо точки квадрата. Тож ми можемо використовувати помилку, щоб вирішити, наскільки хороший у нас квадрат.
Але ми не знаємо впорядкування балів. B і D повинні знаходитися на однаковій відстані від A; якщо ми помножимо це на квадратний корінь на 2, це має бути відстань від А до С. Ми використовуємо це для з'ясування, яка точка є С: Обчислити distB = bx ^ 2 + на ^ 2, distD = dx ^ 2 + dy ^ 2. Якщо distD ≥ 1,5 distB, то ми підміняємо C і D; якщо distB ≥ 1,5 distD, то ми підміняємо C і B. Тепер C правильно.
Ми також можемо визначити, які точки - B і D: Якщо ми здогадалися неправильно, хто з них B, а який - D, то наш обчислення ставить D у абсолютно неправильне місце, прямо навпаки, де воно є. Отже, якщо errD ≥ (bx ^ 2 + by ^ 2), то ми поміняємо B і D.
Це буде правильно розташовувати B, C і D, якщо у нас дійсно є квадрат або хоча б приблизно квадрат. Але якщо у нас немає навіть приблизно квадрата, ми знаємо, що обчислення помилок в кінці покаже це.
Підсумок:
Якщо ми знаємо порядок балів, це, очевидно, може бути спрощено.
Рішення схоже на мислячі засоби масової інформації.
Перший крок:
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
Ця властивість супроводжується квадратом, оскільки вона є циклічною. тепер коло, щоб слідкувати за цим властивістю. так, тепер просто перевірити
if(A.B==B.C==C.D==D.A==0)
f=1
else
f=0
if (f==1)
square
else
not square
Тут AB означає крапковий добуток A і B