Этот фрагмент стека рисует наложенный белый прямоугольник на черном фоне с заданными параметрами для его размеров, положения, угла и размеров сетки:
<style>html *{font-family:Consolas,monospace}input{width:24pt;text-align:right;padding:1px}canvas{border:1px solid gray}</style><p>grid w:<input id='gw' type='text' value='60'> grid h:<input id='gh' type='text' value='34'> w:<input id='w' type='text' value='40'> h:<input id='h' type='text' value='24'> x:<input id='x' type='text' value='0'> y:<input id='y' type='text' value='0'> θ:<input id='t' type='text' value='12'>° <button type='button' onclick='go()'>Go</button></p>Image<br><canvas id='c'>Canvas not supported</canvas><br>Text<br><textarea id='o' rows='36' cols='128'></textarea><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>function toCart(t,a,n,r){return{x:t-n/2,y:r/2-a}}function vtx(t,a,n){return{x:n.x+t*Math.cos(a),y:n.y+t*Math.sin(a)}}function sub(t,a){return{x:t.x-a.x,y:t.y-a.y}}function dot(t,a){return t.x*a.x+t.y*a.y}function inRect(t,a,n,r){var e=sub(a,t),o=sub(a,n),l=sub(a,r),i=dot(e,o),v=dot(e,l);return i>0&&i<dot(o,o)&&v>0&&v<dot(l,l)}function go(){var t=parseInt($("#gw").val()),a=parseInt($("#gh").val()),n=parseFloat($("#w").val()),r=parseFloat($("#h").val()),e={x:parseFloat($("#x").val()),y:parseFloat($("#y").val())},o=Math.PI*parseFloat($("#t").val())/180,l=Math.sqrt(n*n+r*r)/2,i=Math.atan2(r,n),v=vtx(l,o+i,e),h=vtx(l,o+Math.PI-i,e),u=vtx(l,o-i,e),x=$("#c");x.width(t).height(a).prop({width:t,height:a}),x=x[0].getContext("2d");for(var s="",c=0;a>c;c++){for(var f=0;t>f;f++)inRect(toCart(f+.5,c+.5,t,a),v,h,u)?(s+="..",x.fillStyle="white",x.fillRect(f,c,1,1)):(s+="XX",x.fillStyle="black",x.fillRect(f,c,1,1));a-1>c&&(s+="\n")}$("#o").val(s)}$(go)</script>
Текстовое представление имеет XX
везде, где есть черный пиксель на изображении, и ..
везде, где есть белый пиксель. (Это выглядит сжато, если они X
и .
.)
Напишите программу, которая принимает текстовое представление прямоугольника, созданного фрагментом кода, и выводит приблизительную ширину и высоту прямоугольника с точностью до ± 7% от фактической ширины и высоты .
Ваша программа должна эффективно работать со всеми возможными прямоугольниками, которые могут быть нарисованы фрагментом, с ограничениями, которые:
- Ширина и высота прямоугольника не менее 24.
- Ширина и высота сетки не менее 26.
- Прямоугольник никогда не касается и не выходит за границы сетки.
Таким образом, входной прямоугольник может иметь любое вращение, положение и размеры, а сетка может иметь любые размеры при условии соблюдения трех указанных выше ограничений. Обратите внимание, что за исключением размеров сетки, параметры Snippet могут быть плавающими.
Детали
- Возьмите прямоугольник необработанного текста в качестве ввода или имя файла, содержащего прямоугольник необработанного текста (через stdin или командную строку). Вы можете предположить, что у текстового прямоугольника есть завершающий символ новой строки.
- Вы можете предположить, что текстовый прямоугольник состоит из любых двух различных печатаемых символов ASCII, кроме
X
и.
при желании. (Новые строки должны оставаться новыми.) - Выведите измеренную ширину и высоту в виде целых чисел или значений с плавающей точкой в стандартный вывод в любом порядке (поскольку невозможно определить, какой из них на самом деле соответствовал какому параметру). Любой формат , который четко показывает два измерения в порядке, например
D1 D2
,D1,D2
,D1\nD2
,(D1, D2)
и т.д. - Вместо программы вы можете написать функцию, которая принимает текстовый прямоугольник в виде строки или имя файла и печатает результат в обычном режиме или возвращает его в виде строки или списка / кортежа с двумя элементами.
- Помните, что
XX
или..
это один «пиксель» прямоугольника, а не два.
Примеры
Ex. 1
Параметры: grid w:60 grid h:34 w:40 h:24 x:0 y:0 θ:12
(по умолчанию сниппет)
вход
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....XXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX........................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..........................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX................................................................................XXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX................................................................................XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..................................................................................XXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX..........................................................................XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX........................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX....XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Пример выходов
40 24
24 40
[40.0, 24.0]
42.8, 25.68
(+ 7%)37.2, 22.32
(-7%)
Ex. 2
Параметры: grid w:55 grid h:40 w:24.5 h:24 x:-10.1 y:2 θ:38.5
вход
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..............XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXX..................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX......................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX............................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..............................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX......................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX..................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXX......................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX................................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXX..............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXX............................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX......................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXX....................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXX................................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXX............................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXX......................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX..................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX................................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX..........................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXX......................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX..................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX................XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXX..........XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXX......XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Пример выходов
24.0 24.5
25.68 26.215
(+ 7%)22.32 22.785
(-7%)
счет
Самый короткий код в байтах побеждает. Tiebreaker является самым высоко оцененным постом.
Ответы:
Matlab, 226 байт
Идея проста: сначала я пытаюсь выяснить, насколько прямоугольник был повернут, а затем поверните изображение соответствующим образом, чтобы прямоугольник был в вертикальном положении. Затем я просто «суммирую» все пиксели в столбцах строк и пытаюсь подсчитать, сколько сумм выше среднего (простое пороговое значение) для определения ширины и высоты. Этот простой метод работает на удивление надежно.
Как я могу определить угол?
Я просто пробую каждый шаг (по одному градусу), суммирую по столбцам и получаю вектор сумм. Когда прямоугольник выпрямлен, в идеале я должен получить только два внезапных изменения этого вектора сумм. Если квадрат на кончике, изменения очень постепенные. Поэтому я просто использую первую производную и пытаюсь минимизировать количество «прыжков». Здесь вы можете увидеть график критерия, который мы пытаемся минимизировать. Обратите внимание, что вы можете увидеть четыре минимума, которые соответствуют четырем возможным вертикальным ориентациям.
Дальнейшие размышления: я не уверен, сколько это может быть в гольфе, поскольку исчерпывающий поиск углов занимает много символов, и я сомневаюсь, что вы могли бы добиться этого так хорошо с помощью встроенных методов оптимизации, потому что, как вы можете видеть, есть много локальных минимумов что мы не ищем. Вы можете легко улучшить точность (для больших изображений), выбирая меньший размер шага для угла и поиск только 90 ° вместо 360 ° , чтобы вы могли заменить
0:360
с0:.1:90
или somehting подобными. Но в любом случае, для меня проблема заключалась в поиске надежного алгоритма, а не в игре в гольф, и я уверен, что записи языков игры в гольф оставят мое представление далеко позади =)PS: Кто-то должен действительно вывести язык игры в гольф от Matlab / Octave.
Выходы
Пример 1:
Пример 2:
Код
Golfed:
Ungolfed:
источник
CJam,
68 6564 байтаЭто может быть в гольф немного больше ..
Как это устроено
Логика довольно проста, если подумать.
Все, что нам нужно из входных
X.
комбинаций, это 3 координаты двух соседних сторон. Вот как мы их получаем:First
В любой ориентации прямоугольника первый
.
из входных данных будет одним из углов. Например..Здесь первый
.
находится во 2- й строке 8- го столбца.Но это не так, мы должны сделать некоторую корректировку и добавить ширину линии
.
на этой линии к координатам, чтобы получить координату правого конца.Second
Если мы транспонируем вышеуказанный прямоугольник (повернутый на новых строках), то нижний левый угол занимает место вышеуказанного шага. Но здесь мы не компенсируем
.
длину пробега, так как мы хотели бы получить нижнюю левую координату края в любом случае (которая в транспонированной форме все равно будет первой, с которой столкнулись.
)Rest two
Для остальных двух координат мы просто переворачиваем прямоугольник по горизонтали и выполняем два вышеуказанных шага. Один из углов здесь будет общим с первых двух.
После получения всех 4, мы просто делаем простую математику, чтобы получить расстояния.
Сейчас это не самый точный метод, но он хорошо работает в пределах погрешности и хорошо подходит для всех возможных ориентаций прямоугольника.
Расширение кода (немного устаревшее)
Попробуйте онлайн здесь
источник
-2
. Ошибка составляет около 28%. Я попробовал подобный подход (это была моя первоначальная идея, прежде чем увидеть вашу), и получить его достаточно точно оказалось сложнее, чем ожидалось, особенно если стороны близки к горизонтали / вертикали. Прекрасно работает, если они ближе к диагонали. Я думаю, что это требует либо большей логики (например, поиска экстремумов в диагональном направлении), либо совершенно другого подхода..
регулировке ширины по второй координате, а не по первой. Починю. Должно быть короткое исправление.Python 3,
347337 байтЭто оказалось сложнее, чем я ожидал. Работа в процессе...
Определяет функцию
f
принимающую строку в качестве аргумента и печатающую результат в STDOUT.Pyth,
87848281757271 байт(ВОЗМОЖНО НЕДОПУСТИМО, РАССЛЕДОВАТЬ, КОГДА Я ПОЛУЧУ ДОМ
Путьеще слишком длинный. В основном порт предыдущего. Любящее.a
евклидово расстояние Пита . Принимает ввод через STDIN и выдает вывод через STDOUT. Предполагается, что непрямоугольный символ будет строчнымx
(ну, все, что имеет значение ASCII 98 или более).Алгоритм
Оба из них используют один и тот же алгоритм. Я в основном начинаю с массива, содержащего центр масс области прямоугольника. Затем я добавляю три точки в массив всех точек в прямоугольнике, всегда выбирая ту, которая имеет максимальную сумму расстояний до точек, уже находящихся в массиве. В результате всегда три точки в разных углах прямоугольника. Затем я просто вычисляю все три расстояния между этими тремя точками и беру две самые короткие.
источник
[33.0, 59.0]
вместо[40, 24]
и[39.0, 54.0]
вместо[24.0, 24.5]
.Python 2, 342 байта
Это черпало вдохновение из алгоритма @ Pietu1998. Требуется определить один угол как точку, самую дальнюю от центра, но отличается от нее:
Таким образом, код следует этой последовательности:
r
точек прямоугольника.1.0
добавляется к расстоянию, потому что исходные расчеты расстояния используют индексы пикселей. Например, если у вас есть 5 пикселей, разница между индексом последнего и первого пикселя составила всего 4, что требует компенсации в конечном результате.Точность довольно хорошая. Для двух примеров:
источник
Python 2, 272 байта
Публикуем это как отдельный ответ, так как это совершенно другой алгоритм, чем мой предыдущий:
Этот подход не определяет углы вообще. Он основан на наблюдении, что размер (ширина и высота) ограничительной рамки и площадь повернутого прямоугольника достаточны для определения ширины и высоты прямоугольника.
Если вы посмотрите на эскиз, довольно легко вычислить ширину (
wb
) и высоту (hb
) ограничительной рамки сw
/h
размером прямоугольника иp
углом поворота:wb
иhb
может быть извлечен непосредственно из изображения. Мы также можем быстро извлечь общую площадьa
прямоугольника, посчитав количество..
пикселей. Поскольку мы имеем дело с прямоугольником, это дает нам дополнительное уравнение:Таким образом, у нас есть 3 уравнения с 3 неизвестными (
w
,h
иp
), чего достаточно для определения неизвестных. Единственный облом в том, что уравнения содержат тригонометрические функции, и, по крайней мере, с моим терпением и математическими навыками, система не может быть легко решена аналитически.То, что я реализовал, - это грубый поиск угла
p
. Как толькоp
дано, первые два уравнения выше становятся системой двух линейных уравнений, которые могут быть решены дляw
иh
:С этими значениями мы можем сравнить
w * h
с измеренной площадью прямоугольника. Два значения в идеале должны быть равны в какой-то момент. Это, конечно, не произойдет в математике с плавающей точкой.Значение
w * h
уменьшается с увеличением угла. Итак, мы начинаем с угла 0.0, а затем увеличиваем угол небольшими шагами до тех пор, пока первый раз неw * h
станет меньше измеренной площади.Код имеет только два основных шага:
Точность вывода хороша для прямоугольников, где ширина и высота существенно различаются. Это несколько ненадежно с прямоугольниками, которые почти квадратные и повернуты близко к 45 градусам, просто преодолевая 7% -ое препятствие ошибки для тестового примера 2.
Растровое изображение для примера 2 на самом деле выглядит немного странно. Левый угол выглядит подозрительно скучно. Если я добавлю еще один пиксель в левом углу, он будет выглядеть лучше (для меня) и даст гораздо лучшую точность для этого алгоритма.
источник