BBC Basic, 300 caracteres ASCII, tamanho de arquivo tokenised 260
INPUTr,s,u,v,l:r*=8s*=8u*=8v*=8l*=8z=0REPEATz+=1E-3UNTILFNs(z)/z>=SQR(l^2-(v-s)^2)/(u-r)a=(u-r)/2/z
p=(r+u-a*LN((l+v-s)/(l-v+s)))/2q=(v+s-l*FNc(z)/FNs(z))/2MOVE800,0DRAW0,0DRAW0,800CIRCLEu,v,8CIRCLEr,s,8FORx=r TOu
DRAW x,a*FNc((x-p)/a)+q
NEXT
DEFFNs(t)=(EXP(t)-EXP(-t))/2
DEFFNc(t)=(EXP(t)+EXP(-t))/2
Emulador em http://www.bbcbasic.co.uk/bbcwin/bbcwin.html
Obviamente, isso já foi resolvido antes, então a primeira coisa que fiz foi ver o que os outros fizeram.
A equação de uma catenária centrada na origem é simples y=a*cosh(x/a)
. Torna-se um pouco mais complicado se não estiver centrado na origem.
Várias fontes dizem que, se o comprimento e os pontos de extremidade forem conhecidos, o valor a
deverá ser determinado numericamente. Há um parâmetro não especificado h
no artigo da wikipedia. Encontrei outro site e basicamente segui o método aqui: http://www.math.niu.edu/~rusin/known-math/99_incoming/catenary
Como o BBC Basic não possui sinh
e foi cosh
incorporado, defini duas funções no final do programa para calculá-las usandoEXP
as coordenadas do ponto da esquerda devem ser fornecidas antes do ponto da direita, OP confirmou que isso está OK. O comprimento é dado por último. Os valores podem ser separados por vírgulas ou novas linhas.
Código ungolfed
INPUT r,s,u,v,l
REM convert input in range 0-100 to graphic coordinates in range 0-800
r*=8 s*=8 u*=8 v*=8 l*=8
REM solve for z numerically
z=0
REPEAT
z+=1E-3
UNTIL FNs(z)/z>=SQR(l^2-(v-s)^2)/(u-r)
REM calculate the curve parameters
a=(u-r)/2/z
p=(r+u-a*LN((l+v-s)/(l-v+s)))/2
q=(v+s-l*FNc(z)/FNs(z))/2
REM draw axes, 800 graphics units long = 400 pixels long (2 graphics units per pixel)
MOVE 800,0
DRAW 0,0
DRAW 0,800
REM draw markers at end and beginning of curve (beginning last, so that cursor is in right place for next step)
CIRCLE u,v,8
CIRCLE r,s,8
REM draw curve from beginning to end
FORx=r TOu
DRAW x,a*FNc((x-p)/a)+q
NEXT
REM definitions of sinh and cosh
DEF FNs(t)=(EXP(t)-EXP(-t))/2
DEF FNc(t)=(EXP(t)+EXP(-t))/2