De Wikipedia :
El centroide de un polígono cerrado sin intersección propia definido por n vértices ( x 0 , y 0 ), ( x 1 , y 1 ), ..., ( x n - 1 , y n − 1 ) es el punto ( C x , C y ), donde
y donde A es el área firmada del polígono,
En estas fórmulas, se supone que los vértices están numerados en orden de ocurrencia a lo largo del perímetro del polígono. Además, se supone que el vértice ( x n , y n ) es el mismo que ( x 0 , y 0 ), lo que significa que i + 1 en el último caso debe girar alrededor de i = 0 . Tenga en cuenta que si los puntos están numerados en el sentido de las agujas del reloj, el área A , calculada como se indica arriba, tendrá un signo negativo; pero las coordenadas del centroide serán correctas incluso en este caso.
- Dada una lista de vértices en orden (ya sea en sentido horario o en sentido antihorario), encuentre el centroide del polígono cerrado que no se cruza automáticamente representado por los vértices.
- Si ayuda, puede suponer que la entrada es solo CW o solo CCW. Dígalo en su respuesta si necesita esto.
- No se requiere que las coordenadas sean números enteros, y pueden contener números negativos.
- La entrada siempre será válida y contendrá al menos tres vértices.
- Solo es necesario manejar las entradas que se ajusten al tipo de datos de punto flotante nativo de su idioma.
- Puede suponer que los números de entrada siempre contendrán un punto decimal.
- Puede suponer que los enteros de entrada terminan en
.
o.0
. - Puede usar números complejos para la entrada.
- La salida debe ser precisa a la milésima más cercana.
Ejemplos
[(0.,0.), (1.,0.), (1.,1.), (0.,1.)] -> (0.5, 0.5)
[(-15.21,0.8), (10.1,-0.3), (-0.07,23.55)] -> -1.727 8.017
[(-39.00,-55.94), (-56.08,-4.73), (-72.64,12.12), (-31.04,53.58), (-30.36,28.29), (17.96,59.17), (0.00,0.00), (10.00,0.00), (20.00,0.00), (148.63,114.32), (8.06,-41.04), (-41.25,34.43)] -> 5.80104769975, 15.0673812762
Para ver cada polígono en un plano de coordenadas, pegue las coordenadas sin los corchetes en el menú "Editar" de esta página .
Confirmé mis resultados usando esta calculadora de puntos de centroide poligonal , que es horrible. No pude encontrar uno en el que pueda ingresar todos los vértices a la vez, o que no intentara borrar su -
signo cuando lo escribe primero. Publicaré mi solución Python para su uso después de que las personas hayan tenido la oportunidad de responder.
x
s yy
s pone todo el peso en los vértices en lugar de distribuida sobre el cuerpo. El primero funciona porque es regular, por lo que ambos métodos terminan en el centro de simetría. El segundo funciona porque para los triángulos ambos métodos conducen al mismo punto.Respuestas:
Jalea ,
2524222118 bytesAplica la fórmula que se muestra en el problema.
Guardado 3 bytes con ayuda de @ Jonathan Allan.
Pruébalo en línea! o Verificar todos los casos de prueba.
Explicación
fuente
ṁL‘$ṡ2
conṙ1ż@
ożṙ1$
ṙ-ż
para evitar el intercambio y guardar otro byteMathematica, 23 bytes
Toma eso , Jelly!Editar: Uno no simplemente vence a Jelly ...
Explicación
Genere un polígono con vértices en los puntos especificados.
Encuentra el centroide del polígono.
fuente
J, 29 bytes
Aplica la fórmula que se muestra en el problema.
Uso
Explicación
fuente
Máxima,
124 118 116 112106 byteNo tengo experiencia con Maxima, por lo que cualquier sugerencia es bienvenida.
Uso:
fuente
Raqueta 420 bytes
Sin golf:
Pruebas:
Salida:
fuente
R,
129127bytesFunción sin nombre que toma una lista R de tuplas como entrada. El equivalente nombrado se puede llamar usando, por ejemplo:
Desengañado y explicado
El paso final (
c(sum((x+X)*p),sum((y+Y)*p))/sum(p)*2/6
) es una forma vectorizada de calcular ambosCx
yCy
. La suma en las fórmulas paraCx
yCy
se almacena en un vector y, en consecuencia, se divide por la "suma enA
"*2/6
. P.ej:, y luego implícitamente impreso.
Pruébalo en R-Fiddle
fuente
*2/6
probablemente podría ser/3
?sapply
para lidiar con esas listas. Podría haber margen para jugar golf aquí, no estoy seguro de cuán flexible es la entrada permitida. Si se le permite ingresar solo una secuencia de coordenadas, comoc(-15.21,0.8,10.1,-0.3,-0.07,23.55)
, entonces puede guardar 17 bytes reemplazando las primeras líneas de su función cony=l[s<-seq(2,sum(1|l),2)];x=l[-s];
. Es decir, establecery
cada elemento indexado par del
, yx
ser cada elemento indexado impar.matrix(c(-15.21,0.8,10.1,-0.3,-0.07,23.55),2)
, como puede ser el comienzo de su funciónx=l[1,];y=l[2,];
, que ahorra 35 bytes. (La matriz de entrada podría transponerse, en cuyo casox=l[,1];y=l[,2];
). Por supuesto, la solución más fácil de todas es si los puntosx
yy
son simplemente ingresados como vectores separadosfunction(x,y)
, pero no creo que eso esté permitido ...c(...)
) y la conversión de la matriz tendría que hacerse dentro de la función.Python,
156127bytesSin golf:
Ideónalo.
Esto toma cada par de puntos
[x, y]
como un número complejox + y*j
y genera el centroide resultante como un número complejo en el mismo formato.Para el par de puntos
[a, b]
y[c, d]
, el valora*d - b*c
que se necesita para cada par de puntos puede calcularse a partir del determinante de la matrizUsando aritmética compleja, los valores complejos
a + b*j
yc + d*j
se pueden usar comoObserve que la parte imaginaria es equivalente al determinante. Además, el uso de valores complejos permite que los puntos se sumen fácilmente por componentes en las otras operaciones.
fuente
R + sp (46 bytes)
Asume que el
sp
paquete está instalado ( https://cran.r-project.org/web/packages/sp/ )Toma una lista de vértices (por ejemplo
list(c(0.,0.), c(1.,0.), c(1.,1.), c(0.,1.))
)Aprovecha el hecho de que el "labpt" de un polígono es el centroide.
fuente
JavaScript (ES6), 102
Implementación directa de la fórmula
Prueba
fuente
Python 2, 153 bytes
No usa números complejos.
Pruébalo en línea
Sin golf:
fuente
En realidad,
454039 bytesEsto utiliza un algoritmo similar a la respuesta Jelly de miles . Hay una forma más corta de calcular los determinantes usando un producto de puntos, pero actualmente hay un error con el producto de puntos de Actually donde no funcionará con listas de flotadores. Sugerencias de golf bienvenidas. Pruébalo en línea!
Ungolfing
Una versión más corta y no competitiva.
Esta es otra versión de 24 bytes que usa números complejos. No es competitivo porque se basa en correcciones de errores posteriores a este desafío. Pruébalo en línea!
Ungolfing
fuente
C ++ 14, 241 bytes
La salida es la estructura auxiliar
P
,Sin golf:
Uso:
fuente
Clojure,
177156143 bytesActualización: en lugar de una devolución de llamada, estoy usando
[a b c d 1]
una función y el argumento es solo una lista de índices para este vector.1
se usa como valor centinela al calcularA
.Actualización 2: No se calcula previamente
A
enlet
, utilizando(rest(cycle %))
para obtener los vectores de entrada compensados por uno.Versión original:
En la etapa menos golfizada:
Crea una función auxiliar
F
que implementa la suma con cualquier devolución de llamadal
. PorqueA
la devolución de llamada regresa constantemente,1
mientras que las coordenadas X e Y tienen sus propias funciones.(conj(subvec v 1)(v 0))
suelta el primer elemento y se agrega al final, de esta manera es fácil hacer un seguimiento dex_i
yx_(i+1)
. Tal vez todavía quede algo de repetición por eliminar, especialmente al final(map F[...
.fuente