Área de intersección circular

14

Descripción:

Dadas xy las yposiciones de dos círculos junto con su radiisalida del área de intersección de los dos círculos.


Entrada:

Se le dará la siguiente 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

Salida:

  • Un entero no negativo (sin decimal) igual al área de intersección de dos círculos.

  • Una cadena igual al entero antes mencionado.

Nota :

  • La salida debe ser> = 0, ya que el área no puede ser negativa.
  • En caso de redondeo decimal hacia abajo al entero más cercano

Ejemplos:

([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

Criterios ganadores:

Este es el por lo que gana el código más corto en bytes para cada idioma.


Sugerencias:

  • Proporcione un enlace TIO para que pueda probarse.
  • Proporcione una explicación para que otros puedan entender su código.

Estas son solo sugerencias y no son obligatorias.

Muhammad Salman
fuente
44
Ravioli, ravioli ...
FrownyFrog
2
@FrownyFrog: ¿Disculpe? ¿No estoy enterado de lo que estás hablando? nvm verifica en internet y lamento informar que eso es parte del problema. vea la etiqueta que dice matemáticas y geometría. Es una buena excusa para repasar tus matemáticas. Qué piensas. Pero si no está de acuerdo, creo que actualizaré la pregunta y agregaré la fórmula.
Muhammad Salman
@MuhammadSalman Cambiar answer must be positivea answer must be >= 0: si los círculos no se cruzan (como en los ejemplos 4, 7, 10), la respuesta correcta es 0, lo último que comprobé no es positivo.
manassehkatz-Moving 2 Codidact
@manassehkatz: Ok, claro. Hecho
Muhammad Salman el

Respuestas:

3

Gelatina ,  27 25 24  22 bytes

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

Un programa completo que acepta una lista de los dos centros como coordenadas complejas y el radio que imprime el resultado (como un enlace diádico devuelve una lista de longitud 1).

Pruébalo en línea!

Para tomar las dos coordenadas como pares, agregue Uḅıal enlace principal, de esta manera .

¿Cómo?

×,²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
fuente
solo numeros. ¿Y qué es eso [-7 + 13j, -25 + -5j]? No tengo ese ejemplo. Puede que tenga que explicar lo que hizo?
Muhammad Salman
Ya lo expliqué en la respuesta ... son coordenadas en el plano complejo ... Puedo hacerlo, [[x1,y1],[x2,y2]]pero cuesta 3 bytes. (Tenga en cuenta también que -7+13j es un número :)) - [-7+13j,-25+-5j]corresponde al ejemplo que devuelve 132,[-7, 13], [-25, -5], 17
Jonathan Allan
No conozco a Jelly, así que estoy perdido en eso. También envié el mensaje antes de la explicación. Pero sí, claro que esto funciona (¿supongo?)
Muhammad Salman
No tiene nada que ver con Jelly per-se, solo son matemáticas. Un punto en 2 espacios es lo mismo que un número complejo .
Jonathan Allan
No es lo que quise decir. Idiomas normales que podría leer y contar lo que está sucediendo. La gelatina y otros lenguajes similares son difíciles de leer.
Muhammad Salman
3

JavaScript (ES6), 72 bytes

Fórmula alternativa sugerida por @ceilingcat

Toma la 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

Pruébalo en línea!


JavaScript (ES7), 81 80 77 bytes

Guardado 3 bytes gracias a @Neil

Toma la 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

Pruébalo en línea!

¿Cómo?

Esto se basa en una fórmula genérica de MathWorld para círculos no 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

donde d es la distancia entre los dos centros y r y R son los radios.

Con R = r , esto se simplifica a:

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

Y con r '= 2r :

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

Nota : Si d es mayor que 2r , Math.acos()volverá NaN, lo que se convierte en 0 cuando se aplica el desplazamiento a la derecha. Este es el resultado esperado, porque d> 2r significa que no hay intersección en absoluto.

Arnauld
fuente
d*(r*r-d*d)**.5ahorra 3 bytes.
Neil
@ceilingcat Gracias! Usar with(Math)y mover la definición de dahorra 2 bytes más.
Arnauld
3

Mathematica 66 57 51 bytes

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

A se Disk[{x,y},r]refiere a la región circunscrita por el círculo centrado {x,y}con un radio de r.

RegionIntersection[a,b]devuelve la intersección de las regiones a, b. AreaToma el área. IntegerPartRedondea hacia abajo al entero más cercano.

DavidC
fuente
Para el registro, no vi la sumisión de alephalpha ya que estaba haciendo la mía. La suya es una entrada más corta (por lo tanto, más exitosa), pero dejé la mía de todos modos.
DavidC
Podrías reemplazar IntegerPartcon Floor.
matrix89
@mathe, gracias. Si uso los soportes de piso dedicados, ¿sabe cómo contar los bytes?
DavidC
@DavidC cada uno tiene 3 bytes, por lo que la sustitución es neutral en este caso para el recuento de bytes. Sin embargo, son útiles si la expresión necesitara paréntesis (-1 byte en comparación con Floor[ ])
attinat
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

Solo la fórmula, de verdad. El tipo debe declararse como Intpara que NaN se asigne a 0 con floor.

Pruébalo en línea!

Angs
fuente
0

Perl 6 , 56 bytes

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

Pruébalo en línea!

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

nwellnhof
fuente
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 variables separadas:

x-coordinate    y-coordinate    x-coordinate    y-coordinate    radius
     A1              B1             C1                D1          E1
Wernisch
fuente
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)

Pruébalo en línea!

Muy claro. Obtenga la distancia entre círculos y úsela R=2rcomo un sustituto en la ecuación. d<R anda cortocircuito si los círculos no se superponen.

Sunny Patel
fuente
0

Pyth , 63 bytes

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

Banco de pruebas

Toma la entrada como un triple que consta de dos dobles y un número.

hakr14
fuente
0

T-SQL, 122 bytes

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

(salto de línea solo para legibilidad).

Utiliza el soporte de MS SQL de geometría espacial .

Según nuestros estándares IO , SQL puede tomar datos de una tabla t preexistente con el intcampo r y los varcharcampos a y b que contienen coordenadas en el formato(x y) .

Mi declaración analiza las coordenadas como POINTobjetos de geometría expandidos por el radio usando la función STBuffer(), luego toma el STIntersection()seguido por elSTArea() .

Si se me permite ingresar los objetos de geometría reales en la tabla, entonces mi código se vuelve casi trivial (48 bytes):

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