Расширения касательных многоугольников


11

Нарисуйте что-нибудь похожее на это:

введите описание изображения здесь

В более точных терминах нарисуйте круг радиуса r с n равномерно касательными линиями длины l. Соедините концы этих линий, чтобы сформировать новый n-сторонний правильный многоугольник.

правила

r = радиус окружности
n = количество касательных линий - должно быть равномерно распределено по окружности (n> = 3)
l = длина стороны касательных линий

Создайте программу, которая принимает аргументы {r, n, l} и выводит требуемый результат.

Единицы в пикселях.

Нет никаких ограничений на местоположение рисунка, пока все это видно.

Картина довольно понятна.

Это код-гольф, поэтому выигрывает самый короткий код в байтах!


Я предполагаю, что n будет> = 3, есть ли максимум? Хотите ли вы касательные и окружности?
MickyT

Да, n> = 3, (пересечение в порядке, если l не достаточно длинный). Вы должны нарисовать круг и касательные. Я думаю, что максимум в основном, когда на выходе получается заштрихованный круг. Другими словами, максимум - это реалистичный максимум для рисунка, подобного этому.
Стрейч Маньяк

Применяются ли единицы измерения пикселей, если мы производим векторную графику? Потому что в таком случае пиксели на самом деле довольно плохо определены. Или мы должны производить растеризованную графику?
Мартин Эндер

@ MartinBüttner, вы можете игнорировать пиксельные единицы с вашей (причудливой) векторной графикой, если есть какой-то масштаб (например, ось).
Стрейч Маньяк

Ответы:


5

Mathematica, 135 132 131 123 байта

{r,n,l}=Input[];Graphics[{{0,0}~Circle~r,Line[Join@@Array[{b=(a=r{c=Cos[t=2Pi#/n],s=Sin@t})-l{s,-c},a,b}&,n+1]]},Axes->1>0]

Этот код ожидает ввода (через приглашение) точно так, как указано в вопросе: например {100, 6, 150}. Он создает векторную графику, поэтому я включаю ось, как указано в комментариях ОП.

И касательные, и многоугольник на самом деле представляют собой одну полосу, проходя через «угол многоугольника, точку касания, угол многоугольника, следующий угол многоугольника, точку касания, угол многоугольника ...»

введите описание изображения здесь

Если бы не ось, я мог бы сделать это в 107 байтов:

{r,n,l}=Input[];Graphics@{Circle[],Line[Join@@Array[{b=(a={c=Cos[t=2Pi#/n],s=Sin@t})-l/r{s,-c},a,b}&,n+1]]}

Дополнительные сбережения (помимо Axes->1>0) происходят из-за того, что теперь я могу масштабировать все r, что упрощает призыв к Circleполучению круга юнитов.


{0,0}~Circle~r
DavidC

@DavidCarraher хе, я на самом деле уже сделал это в 135 байтах, но забыл скопировать его обратно в свой блокнот, поэтому он изменился, когда я внес изменения в Юникод. благодаря!
Мартин Эндер

8

Python, 133 байта

Пока что единственный ответ - соблюдать правило «Единицы в пикселях» ...

from turtle import*
c=circle
r,n,l=input()
lt(90)
exec'c(r,360/n);fd(l);bk(l);'*n
fd(l)
lt(towards(-r,0)-180)
c(distance(-r,0),360,n)

Добавьте exitonclick()в конец, если вы не хотите, чтобы окно закрывалось немедленно.

Выход:

python tangentpoly.py <<< "20, 6, 30":

введите описание изображения здесь

python tangentpoly.py <<< "100, 8, 200":

введите описание изображения здесь


1
for i in n*[0]:c(r,360/n);fd(l);bk(l)->exec'c(r,360/n);fd(l);bk(l)'*n;
Исаак


7

T-SQL 440 483

Я не собираюсь выигрывать призы, но я люблю рисовать картинки :)

Редактировать Expletive! Просто заметил, что перепутал многоугольники, нарисованные по кругу. Исправлено по стоимости.

SELECT Geometry::UnionAggregate(Geometry::Point(0,0,0).STBuffer(@r).STExteriorRing().STUnion(Geometry::STGeomFromText(CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0))).STUnion(Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing())p FROM(SELECT RADIANS(360./@*N)a,RADIANS((360./@*N)-90)b FROM(SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N FROM sys.types a,sys.types b)t)r

Выполняется со следующими переменными

declare @r float = 1.0
declare @ int = 10
declare @l float = 3.0

Запустите в Sql Server Management Studio 2012+, на вкладке пространственных результатов будет показано следующее. введите описание изображения здесь

С участием

declare @r float = 1.0
declare @ int = 360
declare @l float = 3.0

введите описание изображения здесь

с участием

declare @r float = 10.0
declare @ int = 3
declare @l float = 10.0

введите описание изображения здесь

Расширенный

SELECT Geometry::UnionAggregate(    --group together lines
    Geometry::Point(0,0,0)          --Set origin
    .STBuffer(@r)                   --Buffer to @r
    .STExteriorRing()               --Make it a line
    .STUnion(                       --Join to the floowing tangent
        Geometry::STGeomFromText(   --Create a tangent line
            CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0)
        )
    ).STUnion( --Generate polygon around exterior points
    Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing()
    )
    p
FROM(
    SELECT RADIANS(360./@*N)a,      --calclate bearings
        RADIANS((360./@*N)-90)b
    FROM(                           --make enough rows to draw tangents
        SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N 
        FROM sys.types a,sys.types b
        )t
    )r 

5

MATLAB - 233 байта

function C(n,r,l),t=2*pi/n;c=cos(t);s=sin(t);M=[c,s;-s,c];F=@(y)cell2mat(arrayfun(@(x){M^x*y},1:n));P=F([0;r]);Q=F([l;r]);v='k';t=1e3;t=2*pi/t*(0:t);R=[1:n 1];q=Q(1,R);s=Q(2,R);plot(r*cos(t),r*sin(t),v,[P(1,R);q],[P(2,R);s],v,q,s,v);

Пример выходной функции для n = 8, r = 4, l = 6(оси включены для указания длины блока): циркулярный выход

Пример функции вывода для n = 1024, r = 4, l = 2: циркулярный выход


Я придираюсь к нитям, но единицы в пикселях
Digital Trauma

3
@DigitalTrauma: Ах. Не заметил этого У фигур MATLAB нет фиксированных единиц измерения; они масштабируются к окну. И в любом случае это спорный вопрос. Ваше решение на основе ЛОГО на Python имеет хорошее звучание. До сегодняшнего дня я бы не подумал, что кто-то будет переносить LOGO на Python, но это так. Я учусь по ходу дела. : P
COTO

Ну все равно +1 :)
Цифровая травма

Изображение почти логотип апертуры.
гордый haskeller

4

HTML + JavaScript (E6) 298

Чтобы проверить, сохраните как HTML-файл и откройте с помощью FireFox. Вставьте параметры r, n, l в поле ввода, разделив их запятыми, затем нажмите табуляцию.

Или попробуйте jsfiddle

<input onblur="
[r,n,l]=this.value.split(','),
z=r-~l,t=D.getContext('2d'),w='lineTo',
D.width=D.height=z*2,
t.arc(z,z,r,0,7);
for(C=1,S=i=0;i++<n;)
  t[w](x=z+r*C,y=z+r*S),
  t[w](x-l*S,y+l*C),
  C=Math.cos(a=6.283*i/n),
  S=Math.sin(a),
  t[w](z+r*C-l*S,z+r*S+l*C);
t.stroke()">
<canvas id=D>

Образец вывода

50,20,140

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.