Da Wikipedia :
O centróide de um polígono fechado sem interseção, definido por n vértices ( x 0 , y 0 ), ( x 1 , y 1 ), ..., ( x n - 1 , y n − 1 ) é o ponto ( C x , C y ), onde
e onde A é a área assinada do polígono,
Nestas fórmulas, supõe-se que os vértices sejam numerados em ordem de ocorrência ao longo do perímetro do polígono. Além disso, presume-se que o vértice ( x n , y n ) seja o mesmo que ( x 0 , y 0 ), o que significa que i + 1 no último caso deve fazer um loop em torno de i = 0 . Observe que, se os pontos forem numerados no sentido horário, a área A , calculada como acima, terá um sinal negativo; mas as coordenadas do centróide estarão corretas, mesmo neste caso.
- Dada uma lista de vértices em ordem (no sentido horário ou anti-horário), encontre o centróide do polígono fechado não interceptado por si e representado pelos vértices.
- Se ajudar, você pode assumir que a entrada seja apenas CW ou apenas CCW. Diga isso na sua resposta, se precisar.
- As coordenadas não precisam ser números inteiros e podem conter números negativos.
- A entrada sempre será válida e conterá pelo menos três vértices.
- As entradas só precisam ser manipuladas que se encaixem no tipo de dados de ponto flutuante nativo do seu idioma.
- Você pode assumir que os números de entrada sempre conterão um ponto decimal.
- Você pode assumir que números inteiros de entrada terminam em
.
ou.0
. - Você pode usar números complexos para entrada.
- A saída deve ser precisa até o milésimo mais próximo.
Exemplos
[(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
Veja também cada polígono em um plano de coordenadas, cole as coordenadas sem colchetes no menu "Editar" desta página .
Confirmei meus resultados usando esta Calculadora de pontos centróides do polígono , que é terrível. Não foi possível encontrar um em que você possa inserir todos os vértices de uma só vez ou que não tentou apagar seu -
sinal quando você o digita primeiro. Vou postar minha solução Python para seu uso depois que as pessoas tiverem a chance de responder.
x
s ey
s coloca todo o peso nos vértices em vez de distribuídos ao longo do corpo. O primeiro funciona porque é regular, então os dois métodos acabam no centro de simetria. O segundo funciona porque, para triângulos, os dois métodos levam ao mesmo ponto.Respostas:
Geléia ,
2524222118 bytesAplica a fórmula mostrada no problema.
Economizou 3 bytes com a ajuda de @ Jonathan Allan.
Experimente online! ou Verifique todos os casos de teste.
Explicação
fonte
ṁL‘$ṡ2
porṙ1ż@
oużṙ1$
ṙ-ż
para evitar a troca e salvar outro byteMathematica, 23 bytes
Tome isso , geléia!Edit: Um não basta vencer Jelly ...
Explicação
Gere um polígono com vértices nos pontos especificados.
Encontre o centróide do polígono.
fonte
J, 29 bytes
Aplica a fórmula mostrada no problema.
Uso
Explicação
fonte
Maxima,
124 118 116 112106 byteNão tenho experiência com o Maxima, portanto, qualquer dica é bem-vinda.
Uso:
fonte
Raquete 420 bytes
Ungolfed:
Teste:
Resultado:
fonte
R,
129127 bytesFunção sem nome que recebe uma lista R de tuplas como entrada. O equivalente nomeado pode ser chamado usando, por exemplo:
Ungolfed e explicou
O passo final (
c(sum((x+X)*p),sum((y+Y)*p))/sum(p)*2/6
) é uma maneira vetorizada de calcular ambosCx
eCy
. A soma nas fórmulas paraCx
eCy
é armazenada em um vetor e, consequentemente, dividida pela "soma emA
"*2/6
. Por exemplo:e, em seguida, impresso implicitamente.
Experimente no R-fiddle
fonte
*2/6
provavelmente poderia ser/3
?sapply
para lidar com essas listas! Pode haver espaço para o golfe aqui, não tenho certeza de quão flexível é a entrada permitida. Se você tiver permissão para inserir apenas uma sequência de coordenadas,c(-15.21,0.8,10.1,-0.3,-0.07,23.55)
poderá salvar 17 bytes substituindo as primeiras linhas da sua função pory=l[s<-seq(2,sum(1|l),2)];x=l[-s];
. Ou seja, definiry
para ser todo elemento indexado parl
ex
para ser todo elemento indexado ímpar.matrix(c(-15.21,0.8,10.1,-0.3,-0.07,23.55),2)
pode ser o início de sua funçãox=l[1,];y=l[2,];
, que economiza 35 bytes. (A matriz de entrada pode ser transposta, nesse casox=l[,1];y=l[,2];
.) É claro que a solução mais fácil de todas é se os pontosx
ey
forem apenas inseridos como vetores separadosfunction(x,y)
, mas não acho que isso seja permitido ...c(...)
) e a conversão da matriz teria que ser feita dentro da função.Python,
156127 bytesUngolfed:
Ideone it.
Isso leva cada par de pontos
[x, y]
como um número complexox + y*j
e gera o centróide resultante como um número complexo no mesmo formato.Para o par de pontos
[a, b]
e[c, d]
, o valora*d - b*c
necessário para cada par de pontos pode ser calculado a partir do determinante da matrizUsando aritmética complexa, os valores complexos
a + b*j
ec + d*j
podem ser usados comoObserve que a parte imaginária é equivalente ao determinante. Além disso, o uso de valores complexos permite que os pontos sejam facilmente somados em componentes nas outras operações.
fonte
R + sp (46 bytes)
Assume que o
sp
pacote está instalado ( https://cran.r-project.org/web/packages/sp/ )Leva uma lista de vértices (por exemplo
list(c(0.,0.), c(1.,0.), c(1.,1.), c(0.,1.))
)Aproveita o fato de que o "labpt" de um polígono é o centróide.
fonte
JavaScript (ES6), 102
Implementação direta da fórmula
Teste
fonte
Python 2, 153 bytes
Não usa números complexos.
Experimente online
Ungolfed:
fonte
Na verdade,
454039 bytesIsso usa um algoritmo semelhante à resposta da geléia de milhas . Existe uma maneira mais curta de calcular determinantes usando um produto pontual, mas atualmente há um erro no produto pontual da Actually em que ele não funciona com listas de flutuadores. Sugestões de golfe são bem-vindas. Experimente online!
Ungolfing
Uma versão mais curta e não competitiva
Esta é outra versão de 24 bytes que usa números complexos. Não é competitivo porque se baseia em correções de erros que pós-datam esse desafio. Experimente online!
Ungolfing
fonte
C ++ 14, 241 bytes
Saída é a estrutura auxiliar
P
,Ungolfed:
Uso:
fonte
Clojure,
177156143 bytesAtualização: em vez de um retorno de chamada, estou usando
[a b c d 1]
como uma função e o argumento é apenas uma lista de índices para esse vetor.1
é usado como um valor sentinela ao calcularA
.Atualização 2: Não é pré
A
- calculado emlet
, usando(rest(cycle %))
para obter vetores de entrada compensados em um.Versão original:
Em menos estágio de golfe:
Cria uma função auxiliar
F
que implementa a soma com qualquer retorno de chamadal
. ParaA
o callback retorna constantemente1
, enquanto as coordenadas X e Y têm as suas próprias funções.(conj(subvec v 1)(v 0))
descarta o primeiro elemento e anexa ao final, dessa forma é fácil acompanharx_i
ex_(i+1)
. Talvez ainda exista alguma repetição a ser eliminada, especialmente no final(map F[...
.fonte