Área de interseção do círculo

14

Descrição :

Dados xe yposições de dois círculos, juntamente com os deles radii, produzem a área de interseção dos dois círculos.


Entrada :

Você receberá a seguinte entrada:

array 1 = x and y positions of circle a
array 2 = x and y positions of circle b
radius  = radii of the two congruent circles

Método de entrada :

([12 , 20] , [20 , 18] , 12)     ---> two array and number
([12 , 20 , 20 , 18] , 12)       ---> array and a number
(12 , 20 , 20 , 18 , 12)         ---> all five numbers
('12 20' , '20 18' , 12)         ---> 2 strings and a number
('12 20 20 18' , 12)             ---> string and a number
('12 20 20 18 12')               ---> one string

Resultado :

  • Um número inteiro não negativo (sem decimal) igual à área de interseção de dois círculos.

  • Uma sequência igual ao número inteiro mencionado acima.

Nota :

  • A saída deve ser> = 0, pois a área não pode ser negativa.
  • Em caso de decimal arredondar para baixo para o número inteiro mais próximo

Exemplos :

([0, 0], [7, 0], 5)                   ---> 14

([0, 0], [0, 10], 10)                 ---> 122

([5, 6], [5, 6], 3)                   ---> 28

([-5, 0], [5, 0], 3)                  ---> 0

([10, 20], [-5, -15], 20)             ---> 15

([-7, 13], [-25, -5], 17)             ---> 132

([-12, 20], [43, -49], 23)            ---> 0

Critérios de vitória:

Este é o pelo que o código mais curto em bytes para cada idioma vence.


Sugestões:

  • Forneça um link TIO para que possa ser testado.
  • Forneça uma explicação para que outras pessoas possam entender seu código

Estas são apenas sugestões e não são obrigatórias.

Muhammad Salman
fonte
4
Ravioli, ravioli ...
FrownyFrog 15/04
2
@FrownyFrog: Com licença? Eu não estou ciente do que você está falando? NVM verificar na internet e lamento informar que isso faz parte do problema. veja a tag que diz matemática e geometria. É uma boa desculpa para aprimorar sua matemática. O que você acha. Mas se você não concordar, acho que vou atualizar a pergunta e adicionar a fórmula.
Muhammad Salman
@MuhammadSalman Altere answer must be positivepara answer must be >= 0- Se os círculos não se cruzam (como nos exemplos 4, 7, 10), a resposta correta é 0, e a última vez que verifiquei não é positiva.
usar o seguinte código
@manassehkatz: Ok, claro. Feito
Muhammad Salman

Respostas:

3

Geléia ,  27 25 24  22 bytes

×,²I½
÷ÆAײ}_çHḞ
ạ/çḤ}

Um programa completo que aceita uma lista dos dois centros como coordenadas complexas e o raio que imprime o resultado (como um link diádico, ele retorna uma lista de comprimento 1).

Experimente online!

Para levar as duas coordenadas como pares, adicione Uḅıo link principal, assim .

Quão?

×,²I½ - Link 1, get [√(s²d² - s⁴)]: separation of centres, s; diameter, d
 ,    - pair = [s, d]
×     - multiply (vectorises) = [s², sd]
  ²   - square (vectorises) = [s⁴, s²d²]
   I  - incremental differences = [s²d² - s⁴]
    ½ - square root (vectorises) = [√(s²d² - s⁴)]

÷ÆAײ}_çHḞ - Link 2, get intersection area: separation of centres, s; diameter, d
÷          - divide = s/d
 ÆA        - arccos = acos(s/d)
    ²}     - square right = d²
   ×       - multiply = acos(s/d)d²
       ç   - call last Link (1) as a dyad (f(s,d)) = [√(s²d² - s⁴)]
      _    - subtract (vectorises) = [acos(s/d)d² - √(s²d² - s⁴)]
        H  - halve (vectorises) = [(acos(s/d)d² - √(s²d² - s⁴))/2]
         Ḟ - floor = [⌊(acos(s/d)d² - √(s²d² - s⁴))/2⌋]
           -  ...Note: Jelly's Ḟ takes the real part of a complex input so when
           -           the circles are non-overlapping the result is 0 as required

ạ/çḤ} - Main link: centres, a pair of complex numbers, c; radius, r
 /    - reduce c by:
ạ     -   absolute difference = separation of centres, s
      -   ...Note: Jelly's ạ finds the Euclidean distance when inputs are complex
      -            i.e. the norm of the difference
   Ḥ} - double right = 2r = diameter, d
  ç   - call last Link (2) as a dyad (f(s,d))
      - implicit print
Jonathan Allan
fonte
Apenas números. E o que é isso [-7 + 13j, -25 + -5j]? Eu não tenho esse exemplo. Você pode ter que explicar o que você fez?
Muhammad Salman
Eu já expliquei na resposta ... elas são coordenadas no plano complexo ... posso fazer [[x1,y1],[x2,y2]]isso, mas custa 3 bytes. (Note-se também que -7+13j é um número :)) - os [-7+13j,-25+-5j]corresponde ao exemplo que retorna 132,[-7, 13], [-25, -5], 17
Jonathan Allan
Eu não conheço Jelly, então estou perdido nisso. Também enviei a mensagem antes da explicação. Mas sim, com certeza isso funciona (eu acho?)
Muhammad Salman
Não tem nada a ver com Jelly por si só, é apenas matemática. Um ponto no espaço 2 é o mesmo que um número complexo .
Jonathan Allan
Não foi o que eu quis dizer. Idiomas normais eu seria capaz de ler e dizer o que está acontecendo. Geléia e outras línguas são difíceis de ler.
Muhammad Salman
3

JavaScript (ES6), 72 bytes

Fórmula alternativa sugerida por @ceilingcat

Aceita entrada como 5 parâmetros distintos (x0, y0, x1, y1, r) .

with(Math)f=(x,y,X,Y,r)=>-(sin(d=2*acos(hypot(x-X,y-Y)/r/2))-d)*r*r*2>>1

Experimente online!


JavaScript (ES7), 81 80 77 bytes

Guardado 3 bytes graças a @Neil

Aceita entrada como 5 parâmetros distintos (x0, y0, x1, y1, r) .

(x,y,X,Y,r,d=Math.hypot(x-X,y-Y))=>(r*=2)*r*Math.acos(d/r)-d*(r*r-d*d)**.5>>1

Experimente online!

Quão?

Isso se baseia em uma fórmula genérica do MathWorld para círculos não congruentes:

A = r².arccos((d² + r² - R²) / 2dr) +
    R².arccos((d² + R² - r²) / 2dR) -
    sqrt((-d + r + R)(d + r - R)(d -r + R)(d + r + R)) / 2

onde d é a distância entre os dois centros er e R são os raios.

Com R = r , isso é simplificado para:

A = 2r².arccos(d / 2r) + d.sqrt((2r - d) * (2r + d)) / 2

E com r '= 2r :

A = (r'².arccos(d / r') + d.sqrt(r'² - d²)) / 2

Nota : Se d for maior que 2r , Math.acos()retornará NaN, que será coagido a 0 quando o deslocamento à direita for aplicado. Este é o resultado esperado, porque d> 2r significa que não há interseção.

Arnauld
fonte
d*(r*r-d*d)**.5salva 3 bytes.
Neil
@ceilingcat Thanks! Usar with(Math)e mover a definição de dsalva mais 2 bytes.
Arnauld
3

Mathematica 66 57 51 bytes

Floor@Area@RegionIntersection[#~Disk~#3,#2~Disk~#3]&

A Disk[{x,y},r]refere-se à região circunscrita pelo círculo centrado em {x,y}com um raio de r.

RegionIntersection[a,b]retorna a intersecção das regiões a, b. Areatoma a área. IntegerPartarredonda para baixo para o número inteiro mais próximo.

DavidC
fonte
Para constar, eu não vi a apresentação de alephalpha como estava fazendo a minha. A entrada dele é mais curta (portanto, mais bem-sucedida), mas deixei a minha de qualquer maneira.
21418
Você pode substituir IntegerPartpor Floor.
matrix89
@ mathe, obrigado. Se eu usar os colchetes dedicados, você sabe como devo contar os bytes?
24919
@DavidC cada um tem 3 bytes, portanto a substituição é neutra neste caso para contagem de bytes. Eles são úteis se a expressão precisar de parênteses, no entanto (-1 byte comparado a Floor[ ]).
attinat 24/08/19
1

Haskell , 83 bytes

(k!l)m n r|d<-sqrt$(k-m)^2+(l-n)^2=floor$2*r^2*acos(d/2/r)-d/2*sqrt(4*r*r-d*d)::Int

Apenas a fórmula, realmente. O tipo deve ser declarado como Intpara o NaN mapear para 0 com floor.

Experimente online!

Angs
fonte
fórmula alternativa
ceilingcat 17/04/19
1

JavaScript (Node.js) , 69 bytes

with(Math)f=(a,b,c,d,r)=>(-sin(x=2*acos(hypot(a-c,b-d)/2/r))+x)*r*r|0

Experimente online!

Curto, não tenho certeza se ele pode ser jogado mais. Todas as sugestões são bem-vindas


fonte
0

Perl 6 , 56 bytes

{{1>$_&&{$_-.sin}(2*.acos)}(abs($^p-$^q)/2/$^r)*$r²+|0}

Experimente online!

Toma coordenadas de círculo como números complexos.

Nwellnhof
fonte
0

Excel, 119 bytes

=INT(IFERROR(2*E1^2*ACOS(((C1-A1)^2+(D1-B1)^2)^.5/2/E1)-((4*E1^2-((C1-A1)^2+(D1-B1)^2))*((C1-A1)^2+(D1-B1)^2))^.5/2,0))

Entrada tomada como 5 variáveis ​​separadas:

x-coordinate    y-coordinate    x-coordinate    y-coordinate    radius
     A1              B1             C1                D1          E1
Wernisch
fonte
0

Python 2 , 109 bytes

from math import*
a,b,x,y,r=input()
d,R=hypot(x-a,y-b),2*r
print int(d<R and R*r*acos(d/R)-d*sqrt(R*R-d*d)/2)

Experimente online!

Bem direto. Obtenha a distância entre os círculos e use R=2rcomo um substituinte na equação. d<R andcurto-circuito se os círculos não se sobrepuserem.

Sunny Patel
fonte
0

Pitão , 63 bytes

J@+^-hhQh@Q1 2^-ehQe@Q1 2 2K*2eQs&<JK-**KeQ.tcJK4c*J@-*KK*JJ2 2

Suíte de teste

Aceita entrada como um triplo, composto por dois duplos e um número.

hakr14
fonte
0

T-SQL, 122 bytes

SELECT FLOOR(Geometry::Parse('POINT'+a).STBuffer(r).STIntersection(
             Geometry::Parse('POINT'+b).STBuffer(r)).STArea())FROM t

(quebra de linha apenas para legibilidade).

Usa o suporte do MS SQL à geometria espacial .

Por nossos padrões de IO , SQL pode tirar a entrada de uma tabela pré-existente t com intcampo r e varcharcampos de um e b contendo coordenadas no formato(x y) .

Minha declaração analisa as coordenadas como POINTobjetos de geometria expandidos pelo raio usando a função e STBuffer(), em seguida, obtém o STIntersection()seguido pelo STArea().

Se for permitido inserir os objetos geométricos reais na tabela, meu código se tornará quase trivial (48 bytes):

SELECT FLOOR(a.STIntersection(b).STArea())FROM t
BradC
fonte