Aqui está um mapa de contorno para o qual todos os polígonos dos níveis estão disponíveis.
Vamos perguntar como suavizar os polígonos, mantendo todos os vértices preservados em seus locais exatos?
Na verdade, o contorno é feito sobre os dados da grade, você pode sugerir suavizar os dados da grade e, portanto, o contorno resultante será mais suave. Observe que isso não está funcionando como meu desejo, pois a função de suavização, como o filtro Gaussian, removerá pequenos pacotes de dados e alterará o alcance da terceira variável, por exemplo, a altura que não é permitida no meu aplicativo.
Na verdade, estou procurando um pedaço de código (de preferência em Python ) que possa suavizar os polígonos 2D (qualquer tipo: convexo, côncavo, auto-interceptável etc.) razoavelmente indolor (esqueça as páginas de códigos) e preciso.
Para sua informação, existe uma função no ArcGIS que faz isso perfeitamente, mas o uso de aplicativos comerciais de terceiros não é minha escolha para esta pergunta.
1)
Scipy.interpolate:
Como você vê, as splines resultantes (vermelhas) não são satisfatórias!
2)
Aqui está o resultado usando o código fornecido aqui . Não está funcionando bem!
3)
Para mim, a melhor solução deve ser algo como a figura a seguir, na qual um quadrado está sendo suavizado gradualmente, alterando apenas um valor. Espero um conceito semelhante para suavizar qualquer forma de polígonos.
Satisfazer a condição que o spline passa nos pontos:
4)
Aqui está minha implementação da "idéia do whuber's" linha por linha no Python em seus dados. Possivelmente existem alguns erros, pois os resultados não são bons.
K = 2 é um desastre e, portanto, para k> = 4.
5)
Eu removi um ponto no local problemático e o spline resultante agora é idêntico ao do whuber's. Mas ainda é uma pergunta por que o método não funciona para todos os casos?
6)
Uma boa suavização para os dados do whuber pode ser a seguinte (desenhada pelo software de gráficos vetoriais), na qual um ponto extra foi adicionado sem problemas (compare com a atualização
4):
7)
Veja o resultado da versão Python do código do whuber para obter algumas formas icônicas:
Observe que o método parece não funcionar para polilinhas. Para o canto polilinha (contorno), verde é o que eu quero, mas fiquei vermelho. Isso precisa ser resolvido, pois os mapas de contorno são sempre polilinhas, embora as polilinhas fechadas possam ser tratadas como polígonos, como nos meus exemplos. Também não é que o problema surgido na atualização 4 ainda não tenha sido resolvido.
8) [meu último]
Aqui está a solução final (não perfeita!):
Lembre-se de que você terá que fazer algo sobre a área apontada por estrelas. Talvez haja um erro no meu código ou o método proposto precise de mais desenvolvimento para considerar todas as situações e fornecer os resultados desejados.
Respostas:
A maioria dos métodos para spline seqüências de números spline polígonos. O truque é fazer com que os splines "fechem" suavemente nos pontos finais. Para fazer isso, "envolva" os vértices nas extremidades. Em seguida, divine as coordenadas x e y separadamente.
Aqui está um exemplo de trabalho em
R
. Ele usa ospline
procedimento cúbico padrão disponível no pacote de estatísticas básicas. Para obter mais controle, substituto quase qualquer procedimento que você prefere: apenas certifique-se estrias através dos números (isto é, interpola eles) em vez de simplesmente usá-los como "pontos de controle."Para ilustrar seu uso, vamos criar um polígono pequeno (mas complicado).
Divine-o usando o código anterior. Para tornar o spline mais suave, aumente o número de vértices de 100; para torná-lo menos suave, diminua o número de vértices.
Para ver os resultados, plotamos (a) o polígono original em vermelho tracejado, mostrando o espaço entre o primeiro e o último vértices (isto é, não fechando sua polilinha de limite); e (b) o spline em cinza, mais uma vez mostrando seu espaço. (Como a diferença é muito pequena, seus pontos finais são destacados com pontos azuis).
fonte
Sei que este é um post antigo, mas apareceu no Google para algo que eu estava procurando, então pensei em publicar minha solução.
Não vejo isso como um exercício de ajuste de curva 2D, mas sim em 3D. Ao considerar os dados em 3D, podemos garantir que as curvas nunca se cruzem e podemos usar informações de outros contornos para melhorar nossa estimativa da atual.
O seguinte extrato do iPython usa interpolação cúbica fornecida pelo SciPy. Observe que os valores z que plotei não são importantes, desde que todos os contornos tenham altura eqüidistante.
Os resultados aqui não parecem os melhores, mas com tão poucos pontos de controle, eles ainda são perfeitamente válidos. Observe como a linha verde ajustada é puxada para seguir o contorno azul mais amplo.
fonte
Eu escrevi quase exatamente o pacote que você está procurando ... mas estava no Perl e há mais de uma década: GD :: Polyline . Ele usava curvas cúbicas de Bezier em 2D e "suavizava" um polígono ou "polilinha" arbitrária (meu nome para o que agora é chamado de "LineString").
O algoritmo foi composto de duas etapas: dados os pontos no polígono, adicione dois pontos de controle de Bezier entre cada ponto; em seguida, chame um algoritmo simples para fazer uma aproximação por partes do spline.
A segunda parte é fácil; a primeira parte foi um pouco de arte. Aqui foi o insight: considerar um "segmento de controle" a Vertex N:
vN
. O segmento de controlo era três pontos co-lineares:[cNa, vN, cNb]
. O ponto central era o vértice. A inclinação deste controle seg era igual à inclinação do Vertex N-1 ao Vertex N + 1. O comprimento da porção esquerda deste segmento era 1/3 do comprimento do vértice N-1 ao vértice N, e o comprimento da porção direita desse segmento era 1/3 do comprimento do vértice N ao vértice N + 1.Se a curva original quatro vértices:
[v1, v2, v3, v4]
então a cada vértice agora obter um segmento da forma de controle:[c2a, v2, c2b]
. Junte-os assim:[v1, c1b, c2a, v2, c2b, c3a, v3, c3b, c4a, v4]
e mastigue-os quatro de cada vez, como os quatro pontos de Bezier:,[v1, c1b, c2a, v2]
então[v2, c2b, c3a, v3]
, e assim por diante. Por[c2a, v2, c2b]
serem co-lineares, a curva resultante será suave em cada vértice.Portanto, isso também atende aos seus requisitos para parametrizar o "aperto" da curva: use um valor menor que 1/3 para uma curva "mais apertada", e um valor maior para um ajuste "loopier". Em qualquer um dos casos, a curva resultante sempre passa pelos pontos dados originais.
Isso resultou em uma curva suave que "circunscreveu" o polígono original. Eu também tinha uma maneira de "inscrever" uma curva suave ... mas não vejo isso no código CPAN.
De qualquer forma, no momento não tenho uma versão disponível em Python, nem tenho números. MAS ... se / quando eu portar isso para Python, não deixe de postar aqui.
fonte