Я действительно хотел ромб, но все, что я получил, был этот тупой прямоугольник


33

Учитывая только линейку и компас, вписать ромб внутри данного прямоугольника, разделяя две противоположные точки.

ромб-в-прямоугольник

вход

Входными данными являются размеры прямоугольника. В показанном примере это будет 125, 50. Вы можете вводить данные любым удобным для вас способом (в виде двух целых чисел, списка, строк и т. Д.).

Чем больше размер будет минимум 100, тем меньше будет минимум 25. Обе кепки на 200.

Выход

На выходе будет изображение (отображаемое на экране или сохраненное в виде файла), показывающее

  • Прямоугольник ввода
  • Все «рабочие» линии / круги
  • Вписанный ромб

в разных цветах. На изображении выше прямоугольник черный, рабочие линии синие, а ромб оранжевый. Линии должны быть нарисованы в порядке, указанном в списке (например, ромб перезаписывает рабочие линии и прямоугольник).

Выходное изображение должно быть достаточно большим, чтобы вместить все. Например, показанные круги не могут выходить за пределы.

метод

Метод, использованный в приведенном выше примере изображения:

  • Нарисуйте круг, используя нижний левый угол в качестве центра и верхний правый как точку по периметру, давая радиус, равный диагонали прямоугольника.
  • Сделайте то же самое, но поменяйте местами центр и периметр.
  • Нарисуйте линию между пересечениями двух окружностей, давая перпендикулярную биссектрису диагонали прямоугольника.
  • Используйте пересечения новой линии и прямоугольника, чтобы нарисовать ромб.

Это работает, потому что внутренние диагонали ромба всегда перпендикулярно делят друг друга. Я не привожу здесь полное доказательство этого.

Это не единственный способ получить свой ромб, и вы можете использовать другой, учитывая, что вы объясняете, что делаете. Я считаю, что это, вероятно, самый простой, хотя.

правила

Вы можете рисовать только круги и линии (точнее, отрезки). Круг определяется центральной точкой и точкой периметра. Линия определяется любыми двумя точками. Линии не обязательно должны быть любой заданной длины, но они должны по крайней мере покрывать определяющие точки (обратите внимание на пример изображения: линия проходит немного через пересечения окружностей, но не к краю). Для кругов радиус от центра до выбранной точки периметра считается рабочей линией и должен быть показан.

Чтобы растеризовать линии, вы можете использовать любой распознанный алгоритм (например, алгоритм Брезенхэма) или полагаться на то, что может иметь ваш встроенный язык. Если ваши выходные данные основаны на векторах, убедитесь, что они отображаются с разрешением, по крайней мере равным входному прямоугольнику в пикселях. Кроме того, вы будете рисовать на простом холсте, поэтому, пожалуйста, подавьте любые метки сетки или посторонний вывод.

Без обмана! Вы можете только определить расположение точек / линий / кругов, используя то, что вы уже установили. Если вы не можете объяснить, как использовать ваши рабочие линии / круги, чтобы показать, что это ромб, вы делаете это неправильно.

Вы можете использовать любую пару противоположных точек, которую хотите, и прямоугольник не нужно рисовать по оси, если выходные данные верны.

Ввод всегда будет не прямоугольным прямоугольником, поэтому не беспокойтесь об этом в специальном регистре.

Наконец, это стандартный код гольф, поэтому выигрывает самый низкий размер в байтах.


Можем ли мы использовать математическую формулу для определения, например, конечных точек линии, проведенной между пересечениями окружностей после их прорисовки (без фактического анализа изображения, чтобы увидеть, где находятся пересечения)?
ETHproductions

@ETHproductions Я бы сказал, да, так как довольно легко показать, что угол между ними и радиусом составляет 60 градусов с каждой стороны, и что они образуют равносторонние треугольники. Если у кого-то есть возражения, я тоже хочу это услышать.
Geobits

3
Можем ли мы предположить, что первый вход будет больше, чем второй (или наоборот), или ответы должны быть в состоянии обрабатывать как вертикально, так и горизонтально ориентированные прямоугольники?
Мартин Эндер,

Какова цель короткого отрезка внутри прямоугольника?
12Me21

Ответы:


11

HTML + JavaScript (ES6), 34 + 353 = 387 байт

Ввод должен быть дан в формате [125,50].

[w,h]=eval(prompt(c=C.getContext("2d"))).sort();d=q=>(c.strokeStyle=q,b);l=(x,y=Z)=>x?c.lineTo(x,y)||l:c.stroke();b=(x,y=H,r)=>(c.beginPath(),r?c.arc(x,y,Math.sqrt(r),0,2*Math.PI):c.moveTo(x,y),l);b(Z=300,Z)(W=Z+w)(W,H=Z+h)(Z,H)(Z)();d`red`(Z,H,s=w*w+h*h)();b(W,Z,s)();b(Z)(W)();b(Z+w/2-h,Z+h/2-w)(H+w/2,W+h/2)();d`lime`(Z)(W-s/2/w)(W)(Z+s/2/w,H)(Z,H)()
<canvas id=C width=800 height=800>

Просто много математики и рисования ... Прямоугольник рисуется вбок, если высота больше ширины, что, я считаю, допустимо.


Оооо, на 10 байт меньше, чем 444: P
Kritixi Lithos

@KritixiLithos Теперь я на 10 байтов меньше 400;-)
ETHproductions

Прямоугольник вписывается в ромб, когда высота больше ширины.
Larkeith

1
@Larkeith Ой, не знал, что мы должны были покрыть те случаи. Исправлено по стоимости 42 байта.
ETHproductions

Вы можете использовать "getContext` 2d `" (без пробелов), чтобы сохранить несколько байтов (почему они должны были использовать `и прерывать уценку ...)
12Me21

10

Mathematica, 157 148 158 байт

Спасибо Martin Ender за комментарии с их обычным высоким качеством! 9 байтов сохранено в этом случае.

Отредактировано, как только выяснилось, что аргументы могут прийти в любом порядке; 10 байтов добавлено для компенсации.

Graphics@{(m=Line)@{o=0{,},{#,0},c={##},{0,#2},o},Blue,m[l={o,c}],Circle[#,(c.c)^.5]&/@l,m[{k={#2,-#},-k}+{c,c}/2],Red,m@{o,p={0,c.c/2/#2},c,c-p,o}}&@@Sort@#&

Опять же, именно здесь Mathematica сияет: высокоуровневый графический вывод, включающий математические вычисления. Тот же код с пробелами и символами новой строки для удобства чтения:

Graphics@{
  (m=Line)@{o = 0{,}, {#, 0}, c = {##}, {0, #2}, o},
  Blue, m[l = {o, c}], Circle[#, (c.c)^.5] & /@ l, 
  m[{k = {#2, -#}, -k} + {c, c}/2],
  Red, m@{o, p = {c.c/2/#2, 0}, c, c - p, o}
} & @@ Sort@# &

Безымянная функция одного аргумента, который представляет собой упорядоченную пару положительных чисел; финал @@ Sort@# &преобразует эту пару в два числовых аргумента, где первое число меньше. Lineсоздает многоугольный путь от точки к точке, который превратится в замкнутый многоугольник, если первая и последняя точки совпадают; Circleсоздает круг с заданным центром и радиусом. Специальные точки oи c(нижний левый и верхний правый углы прямоугольника)p (третий угол ромба, заданный математической формулой) и k(помогая нарисовать перпендикулярный биссектрису) даны имена по пути для сохранения байтов при повторном вызове , как особая пара точекl = {o,c}, Mathematica рада добавить точки напрямую, умножить обе координаты на один и тот же коэффициент, взять их точечное произведение и т. Д., И все это упрощает код.

Пример вывода с аргументами 125и 50:

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


1
Re ненужных пробелов. Вы можете использовать этот трюк, чтобы сохранить байт {0,0}. Поскольку нет необходимости использовать синий и оранжевый цвета, вы можете сохранять байты, используя Redвместо Orange. Вы используете Lineчетыре раза, что более чем достаточно для сохранения байтов i=Line;(как правило, если в выражении есть nсимволы и вы используете его mраз, когда вам нужно (m-1)*(n-1) > 4, меньше, если вы можете назначить переменную при первом использовании без скобок).
Мартин Эндер,

Этот 0{,}трюк фантастический: D
Грег Мартин

Боюсь, это не сработает, если вторая сторона длиннее первой. Однако ориентация не нужно быть последовательным, так что это может быть исправлено путем добавления @@Sort@#&и замены #и в #2течение кода или , альтернативно , адаптируя его к работе с портретной ориентации прямоугольников вместо.
Мартин Эндер

Да, это было преднамеренно ... похоже, мы ожидаем разъяснения о том, можем ли мы предположить, что измерения приходят в том порядке, в котором мы хотим.
Грег Мартин


9

MetaPost, 473 (с цветом) 353 (без цвета)

Цветной (473 байта):

A:=170;B:=100;pair X,Y;path C,D,E,F,G,R,T;X=(0,0);Y=(A,B);R=X--(A,0)--Y--(0,B)--cycle;T=(0,B)--(A,B);draw R;E=X--Y;C=X..Y*2..cycle;D=Y..-Y..cycle;F=(D intersectionpoint C)--(C intersectionpoint D);draw C withcolor green;draw D withcolor green;draw E withcolor red;draw F withcolor red;draw (F intersectionpoint R)--Y withcolor blue;draw X--(F intersectionpoint T) withcolor blue;draw (F intersectionpoint T)--Y withcolor blue;draw (F intersectionpoint R)--X withcolor blue;

Неокрашенный (353 байта):

A:=170;B:=100;pair X,Y;path C,D,E,F,G,R,T;X=(0,0);Y=(A,B);R=X--(A,0)--Y--(0,B)--cycle;T=(0,B)--(A,B);draw R;E=X--Y;C=X..Y*2..cycle;D=Y..-Y..cycle;F=(D intersectionpoint C)--(C intersectionpoint D);draw C;draw D;draw E;draw F;draw (F intersectionpoint R)--Y;draw X--(F intersectionpoint T);draw (F intersectionpoint T)--Y;draw (F intersectionpoint R)--X;

Никогда НИКОГДА не использовал это раньше, и я уверен, что я убил это ...
Но когда вы запустите это на этом сайте:

http://www.tlhiv.org/mppreview/

Он использует пересечение окружностей, чтобы нарисовать вторую ось, а затем использует пересечение оси и прямоугольника, чтобы нарисовать заключительный ромб. Хотя я мог бы обмануть и просто нарисовал линию, перпендикулярную первой оси, ха-ха.

Чтобы изменить размеры, просто измените A и B.

Независимо от этого вы получите (для L = 170, H = 100):

Образ


3

Desmos, 375 (или 163) байтов

w=125
h=50
\left(wt,\left[0,h\right]\right)
\left(\left[0,w\right],ht\right)
\left(x-\left[0,w\right]\right)^2+\left(y-\left[0,h\right]\right)^2=w^2+h^2
\frac{h}{w}x\left\{0\le x\le w\right\}
-\frac{w}{h}\left(x-\frac{w}{2}\right)+\frac{h}{2}
a=\frac{h^2}{2w}+\frac{w}{2}
\left(t\left(w-a\right)+\left[0,1\right]a,ht\right)
\left(at-\left[0,a-w\right],\left[0,h\right]\right)

wи hявляются входными данными. Попробуйте это на Desmos!

Альтернативная 163-байтовая версия:

w=125
h=50
(wt,[0,h])
([0,w],ht)
(x-[0,w])^2+(y-[0,h])^2=w^2+h^2
hx/w\left\{0\le x\le w\right\}
-w(x-w/2)/h+h/2
a=h^2/2/w+w/2
(t(w-a)+[0,1]a,ht)
(at-[0,a-w],[0,h])

Эта версия требует, чтобы каждая строка была скопирована и вставлена ​​в каждую отдельную строку в Desmos. Мета все еще должен решить, является ли это действительным методом подсчета, но первый метод определенно хорош.


Кажется, это предполагает, что входной прямоугольник находится в альбомной ориентации, которая не указана в задаче.
Хеннинг Махолм

1
Для меня «прямоугольник не должен быть нарисован по оси» подразумевает, что на прямоугольнике нет предопределенной ориентации, включая пейзаж или портрет, который необходимо сохранить.
Грег Мартин

Поскольку указан только размер (не координаты), выходные данные могут быть выровнены, как вам угодно, при условии, что размер правильный.
Geobits

Впервые я вижу, как Desmos используется в качестве языка для игры в гольф :)
Kritixi Lithos

3

ImageMagick версия 7.0.3 + bash + sed, 496 байт

M=magick
L=$((400-$(($1))/2)),$((400+$(($2))/2))
R=$((400+$(($1))/2)),$((400-$(($2))/2))
Z=" $L $R" Y=" -1 x";D=' -draw' K=' -stroke'
A=' -strokewidth 3 +antialias -fill'
$M xc:[800x]$A none$K \#000$D "rectangle$Z"$D "line$Z"$K \#00F8$D "circle$Z"$K \#0F08$D "circle $R $L" -depth 8 png:a
$M a txt:-|sed "/38C/!d;s/:.*//">x;P=`head$Y`;Q=`tail$Y`
$M a$A \#F008$K \#F008$D "line $P $Q" b
$M b txt:-|sed "/C70/!d;s/:.*//">x;S=`head$Y`;T=`tail$Y`
$M b$A \#F804$K \#F80$D "polyline $L $S $R $T $L" x:

Результат с "rhombus.sh 180 120"

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

Точнее (используя холст 6400х6400 вместо 800х800), 570 байт

Пересечения не точны; директива strokewidth делает линии достаточно широкими, чтобы обеспечить смешивание хотя бы одного целого пикселя только с цветами двух пересекающихся линий, но в худших случаях (25x200 и 200x25) пересечения находятся под небольшим углом, поэтому облако длина смешанных пикселей составляет несколько пикселей, и поскольку мы выбираем первый и последний смешанный пиксель, возникает небольшая ошибка. Использование холста большего размера в 8 раз с той же шириной штриха, а затем масштабирование результата уменьшает ошибку до менее чем одного пикселя, но примерно в 64 раза быстрее.

M=magick
L=$((3200-$(($1))*4)),$((3200+$(($2))*4))
R=$((3200+$(($1))*4)),$((3200-$(($2))*4))
K=-stroke;A='-strokewidth 3 +antialias'
$M xc:[6400x] $A -fill none $K \#000 -draw "rectangle $L $R" \
-draw "line $L $R" $K \#00F8 -draw "circle $L $R" \
$K \#0F08 -draw "circle $R $L" -depth 8 png:a 
$M a txt:-|grep 38C077|sed -e "s/:.*//p">x
P=`head -1 x`;Q=`tail -1 x`
$M a $A -fill \#F008 $K \#F008 -draw "line $P $Q" png:b
$M b txt:-|grep C70000|sed -e "s/:.*//p">x
S=`head -1 x`;T=`tail -1 x`
$M b $A -fill \#F804 $K \#F80 -draw "polyline $L $S $R $T $L" -resize 800 x:

Результаты нормального 800x800 против точного 6400x6400:

нормальный против точных результатов

Ungolfed:

# rhombus.sh
# Inscribe a rhombus in the rectangle with dimensions 2*$1, 2*$2

# Run with "rhombus.sh W H"

M=magick

W=${1:-100};H=${2:-40}

# L locates the lower left corner of the rectangle
L=$((400-$((W))/2)),$((400+$((H))/2))

# R locates the upper right corner of the rectangle
R=$((400+$((W))/2)),$((400-$((H))/2))

# We'll need this several times
A='-strokewidth 3 +antialias'

# Establish 800x800 canvas (white) (circles + rectangle will
# always fit in 764x764)
#
# Draw the W x H rectangle (black) in center of canvas
#
# Draw two circles (blue, 50% alpha [#00F8] and green, 50% alpha [#0F08])
#  one centered at point L with peripheral point R
#  the other centered at point R with peripheral point L

$M xc:[800x] $A -fill none \
       -stroke \#000  -draw "rectangle $L $R" \
                      -draw "line      $L $R" \
       -stroke \#00F8 -draw "circle    $L $R" \
       -stroke \#0F08 -draw "circle    $R $L" \
       -depth 8 a.png 

# Find P and Q, the 2 intersections of the circles,
# that have mixed color #38C077 
$M a.png txt:-|grep 38C077|sed -e "s/:.*//p">x
P=`head -1 x`;Q=`tail -1 x`

# Draw line connecting the intersections P and Q
$M a.png $A -fill \#F008 -stroke \#F008 -draw "line $P $Q" b.png

# Find S and T, the 2 intersections of the line with the original rectangle,
# that have mixed color #C70000
$M b.png txt:-|grep C70000|sed -e "s/:.*//p">x
S=`head -1 x`;T=`tail -1 x`

# Draw the rhombus
$M b.png $A -fill \#F804 -stroke \#F80 -draw "polyline $L $S $R $T $L" d.png

Мне нравится, как вы обнаруживаете пересечения, очень приятно. Последний смешанный цвет правильный? Я спрашиваю, потому что похоже, что ромб и прямоугольные линии немного смещены. Я подумал, что, возможно, цвет был обнаружен в слегка смещенном месте из-за сглаживания (возможно, также ширины обводки).
Geobits

2

R, 290 байт

function(A,B,p=polygon){R=A^2+B^2
D=2*A
a=sqrt(R)*cbind(cos(t<-seq(0,2*pi,.01)),sin(t))
b=t(t(a)+c(A,B))
x=range(a,b)
plot(NA,xli=x,yli=x,as=1,ax=F,an=F)
rect(0,0,A,B)
segments(0,0,A,B,c=4)
p(a,b=4)
p(b,b=4)
curve(B/2-A*x/B+A^2/2/B,co=4,a=T)
p(cbind(c((R-2*B^2)/D,A,R/D,0),c(B,B,0,0)),b=3)}

Анонимная функция, вывод отображается на экране. Слегка разгоряченный, с комментариями:

function(A,B){
    R=A^2+B^2
    D=2*A
    t=seq(0,2*pi,.01)
    a=sqrt(R)*cbind(cos(t),sin(t)) #Circle with (0,0) as center
    b=t(t(a)+c(A,B)) #Second circle transposed to (A,B) center
    x=range(a,b)
    #Empty plot, large enough to fit the 2 circles:
    plot(NA,xlim=x,ylim=x,asp=1,axes=F,ann=F)
    rect(0,0,A,B) #Initial rectangle
    segments(0,0,A,B,col=4) #Rectangle diagonal
    polygon(a,border=4) #Circle 1 (border is b thanks to partial matching)
    polygon(b,border=4) #Circle 2
    curve(B/2-A*x/B+A^2/2/B,col=4,add=T) #Line joining circles intersection
    polygon(cbind(c((R-2*B^2)/D,A,R/D,0),c(B,B,0,0)),border=3) #Rhombus
}

Пример вывода для (120 100):

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


2

LibreLogo , 270 байт

Пользовательский ввод принимается как массив: [width, height]или [height, width].

Код:

fc [24]
D=180
R=sorted(eval(input "))
W=R[1]
H=R[0]
L=sqrt W**2+H**2
A=D/π*asin(H/L)
Z=A*2
S=L/2/cos A*π/D rectangle[W,H]pc 255 lt A fd 400 bk 800 fd 400 rt A pu bk H/2 lt 90 fd W/2 pd circle L*2 rt D-A fd L circle L*2 pc [5]lt D-A fd S lt Z fd S rt D+Z fd S lt Z fd S

Результат:

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

Объяснение:

fc [24]                        ; Fill Color = Invisible
D = 180                        ; D = 180° (Saved Bytes)
R = sorted( eval( input " ) )  ; R = Sorted Array of Rectangle Width and Height (User Input)
W = R[1]                       ; W = Rectangle Width
H = R[0]                       ; H = Rectangle Height
L = sqrt W**2 + H**2           ; L = Rectangle Diagonal Length
A = D / π * asin( H / L )      ; A = Rectangle Diagonal Angle°
Z = A * 2                      ; Z = Rectangle Diagonal Angle° * 2 (Saved Bytes)
S = L / 2 / cos A * π / D      ; S = Rhombus Side Length
rectangle [W, H]               ; Draw Rectangle
pc 255                         ; Pen Color = Blue
lt A                           ; Left = Rectangle Diagonal Angle°
fd 400                         ; Forward = 400 pt
bk 800                         ; Back = 800 pt
fd 400                         ; Forward = 400 pt
rt A                           ; Right = Rectangle Diagonal Angle°
pu                             ; Pen Up
bk H / 2                       ; Back = Rectangle Height / 2
lt 90                          ; Left = 90°
fd W / 2                       ; Forward = Rectangle Width / 2
pd                             ; Pen Down
circle L * 2                   ; Draw Left Circle (Radius = Rectangle Diagonal Length)
rt D - A                       ; Right = 180° - Rectangle Diagonal Angle°
fd L                           ; Forward = Rectangle Diagonal Length
circle L * 2                   ; Draw Right Circle (Radius = Rectangle Diagonal Length)
pc [5]                         ; Pen Color = Red
lt D - A                       ; Left = 180° - Rectangle Diagonal Angle°
fd S                           ; Forward = Rhombus Side Length
lt Z                           ; Left = Rectangle Diagonal Angle° * 2
fd S                           ; Forward = Rhombus Side Length
rt D + Z                       ; Right = 180° + Rectangle Diagonal Angle° * 2
fd S                           ; Forward = Rhombus Side Length
lt Z                           ; Left = Rectangle Diagonal Angle° * 2
fd S                           ; Forward = Rhombus Side Length

1

Python 3.5 + Tkinter, 433 или 515 байт

Неокрашенный (433 байта):

from tkinter import*
def V(a,b):S=500;Y,Z=S+a,S-b;M=(a**2+b**2)**0.5;D=Tk();C=Canvas(D);B=C.create_oval;X=C.create_line;B(S+M,S-M,S-M,S+M);B(Y-M,Z+M,Y+M,Z-M);X(Y,Z,S,S);C.create_rectangle(Y,S,S,Z);Q=-((Z-S)/(Y-S))**-1;U,V=(Y+S)/2,(Z+S)/2;X(U+M,V+M*Q,U-M,V-M*Q);P=[(Y,Q*(Y-U)+V),(((Z-V)/Q)+U,Z)][a>b];L=[(S,Q*(S-U)+V),(((S-V)/Q)+U,S)][a>b];X(S,S,P[0],P[1]);X(Y,Z,P[0],P[1]);X(Y,Z,L[0],L[1]);X(S,S,L[0],L[1]);C.pack(fill=BOTH,expand=1)

Цветной (515 байт):

from tkinter import*
def V(a,b):S=500;t='blue';Y,Z=S+a,S-b;M=(a**2+b**2)**0.5;D=Tk();C=Canvas(D);B=C.create_oval;X=C.create_line;B(S+M,S-M,S-M,S+M,outline=t);B(Y-M,Z+M,Y+M,Z-M,outline=t);X(Y,Z,S,S,fill=t);C.create_rectangle(Y,S,S,Z);Q=-((Z-S)/(Y-S))**-1;U,V=(Y+S)/2,(Z+S)/2;X(U+M,V+M*Q,U-M,V-M*Q,fill=t);P=[(Y,Q*(Y-U)+V),(((Z-V)/Q)+U,Z)][a>b];L=[(S,Q*(S-U)+V),(((S-V)/Q)+U,S)][a>b];o='orange';X(S,S,P[0],P[1],fill=o);X(Y,Z,P[0],P[1],fill=o);X(Y,Z,L[0],L[1],fill=o);X(S,S,L[0],L[1],fill=o);C.pack(fill=BOTH,expand=1)

Именованная функция, которая принимает входные данные как 2 числа, разделенных запятыми. Вывод дается в отдельном окне, которое вам может потребоваться изменить размер, чтобы увидеть полный вывод. Вот пример цветного вывода для V(180,130):

Пример вывода


0

SmileBASIC, 280 байт

INPUT W,H
W=MAX(W,H)/4H=MIN(W,H)/4D=SQR(W*W+H*H)N=D+W
M+D+H
GBOX D,D,N,M,#RED
GCIRCLE D,M,D
GCIRCLE N,D,D
GLINE D,M,N,D
X=D+W/2Y=D+H/2A=ATAN(W,H)E=D*H/W/2S=E*COS(A)T=E*SIN(A)GLINE X-S*9,Y-T*9,X+S*9,Y+T*9GCOLOR-#L
GLINE D,M,X-S,Y-T
GLINE D,M,X+S,M
GLINE N,D,X+S,Y+T
GLINE N,D,X-S,D

(Снимок экрана / объяснение будет опубликовано в ближайшее время) Цвет фона - черный, прямоугольник - красный, круги и линии - белый, а ромб - желтый.

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