Como faço para converter entre dois sistemas de coordenadas 2D diferentes?

10

Estou tentando converter uma coordenada de um sistema de coordenadas para outro, para que eu possa desenhar em uma imagem.

Basicamente, o sistema de coordenadas de destino é o seguinte:

X range: 0 to 1066
Y range: 0 to 1600

(apenas uma imagem padrão na qual estou desenhando com o tamanho de 1066 x 1600)

A posição que estou tentando desenhar na imagem tem exatamente o mesmo tamanho, mas o sistema de coordenadas é diferente. O período de todas as coordenadas é 1066x1600.

Mas um exemplo de coordenadas seria:

(111.33f, 1408.41f)
(-212.87f, 1225.16f)

O alcance deste sistema de coordenadas é:

X range: -533.333 to 533.333
Y range: 533.333 to 2133.333

Eu sinto que isso é matemática MUITO simples, mas por alguma razão eu não estou entendendo.

Como posso converter as coordenadas fornecidas no primeiro sistema de coordenadas?

Geesu
fonte
3
Se os dois sistemas de coordenadas tiverem os mesmos vetores de base, você pode simplesmente usar um fator de escala. Se eles não tiverem os mesmos vetores de base, é necessária uma alteração de base .
Thalador

Respostas:

7

Você pode normalizar o primeiro valor, isso fornecerá um valor no intervalo [0,1]. Você pode pensar nisso como X porcentagem, a porcentagem que o valor é mapeado entre os valores mínimo e máximo. Em seguida, você pode descobrir onde essa porcentagem pertence ao seu sistema de coordenadas de destino, vendo qual valor é X porcentagem no sistema de destino. Vou usar o código Java como uma linguagem de exemplo. Tenho certeza de que os conceitos são claros o suficiente para traduzir para qualquer linguagem.

Então normalize:

public static float normalize(float value, float min, float max) {
    return Math.abs((value - min) / (max - min));
}

Usando seu exemplo, você inseriu:

xPercent = normalize(x,0,1066);

Em seguida, encontre onde está o sistema de destino. Com algo como

destX = xPercent*(Math.abs(max-min)) + min;

Ou para usar seus valores:

destX = xPercent*(Math.abs(533.33--533.33)) + -533.33;

Assim, por exemplo, com um valor x de 1000, você mapeará isso para o seu sistema de coordenadas de destino 467.29.

Como alternativa , se os sistemas de coordenadas sempre forem os mesmos, você poderá pré-calcular a proporção entre eles.

Assim:

xRatio = (Math.abs(srcMax-srcMin))/(Math.abs(destMax-destMin));

destX = x*xRatio+destMin;
MichaelHouse
fonte
Por que Java (C #)? Ele não pediu para o código Java :)
kravemir
6
É para dar um exemplo. Ele não precisa ser usado como está e o conceito é claro o suficiente.
MichaelHouse
Mas se eu fizer isso: destX = xPercent * (Math.abs (533.33-533.33)) + -533.33; Eu sempre recebo um valor negativo, e o sistema de coordenadas do resultado é apenas de 0 a 1066, devo mudar todas as coordenadas?
Geesu 18/07/12
Troquei-os e ainda estou recebendo o dump.tanaris4.com/sota.png, como em outro post, talvez esteja tendo outro problema (relacionado a C # e desenho). Obrigado rapazes!
Geesu 18/07/12
Entendi, por alguma razão, eu tinha que fazer xPercent = 1.0f - xPercent
Geesu
4

É uma matemática simples:

res = ( src - src_min ) / ( src_max - src_min ) * ( res_max - res_min ) + res_min

src - sistema de coordenadas de origem

res - sistema de coordenação de resultados

Editar - explicação da matemática

( src - src_min ) / ( src_max - src_min )converte-o para coordenar o sistema começando em zero com o mesmo comprimento do sistema de coordenadas de origem (0.0, src_max - src_min ). Em seguida, ele escala o valor para coordenar o sistema (0.0, 1.0).

* ( res_max - res_min ) isso dimensiona o valor para coordenar o sistema começando em zero com o comprimento do sistema de coordenação de resultados (0.0, dst_max - dst_min)

+ res_min converte valor no sistema de coordenadas resultante (dst_min, dst_max)

kravemir
fonte
Pensei isso também, mas não é exibido corretamente: dump.tanaris4.com/sota.png A cota final deve bater onde o círculo branco está no fundo
Geesu
1
Isso não explica nada de matemática, por que não? :)
MichaelHouse
@ Byte56 Para mim é a fórmula suficiente para entender alguma coisa, especialmente se ele usa apenas operações aritméticas, mas eu adicionei explicação para as pessoas que precisam dele :)
kravemir
1
@ Geesu Então você provavelmente está fazendo outra coisa ruim (renderizando matrizes?).
Kravemir
2
Obrigado por atualizar isso. Geralmente, acho melhor dar uma resposta que tente explicar o porquê. Caso contrário, você está apenas dando a resposta a esta pergunta, em vez de como resolvê-la e problemas semelhantes. É uma coisa do tipo "dê um peixe a um homem, ensine um homem a pescar".
MichaelHouse
3

A equação básica para a transformação de coordenadas 2D (em álgebra, sem rotação envolvida) é:

TargetCoordinate = TranslateFactor + ScalingFactor*SourceCoordinate

dado dois pontos no TargetCoordinate (T1, T2) que corresponde a dois pontos no SourceCoordinate (S1, S2) TranslateFactore ScalingFactoré dado resolvendo:

T1 = TranslateFactor + ScalingFactor*S1
T2 = TranslateFactor + ScalingFactor*S2

qual resultado:

TranslateFactor = (T2*S1 - T1*S2) / (S1 - S2)
ScalingFactor   = (T2 - T1) / (S2 - S1)

No seu caso, para a coordenada x

S1 = 0    -> T1 = -533.333
S2 = 1066 -> T2 = 53.333

E assim,

TranslateFactor = -533.333
ScalingFactor   = 1.000625
=> TargetCoordinate = (-533.333) + (1.000625)*SourceCoordinate

As coordenadas y seguem o mesmo procedimento

tkokasih
fonte
S1 e S2 não podem ter a mesma coordenada x / y que leva a uma divisão por zero.
Zwcloud
0

Fazendo algumas suposições:

  • Você está (eventualmente) interessado em uma implementação da matriz, por conveniência e poder; e
  • Você está familiarizado com coordenadas homogêneas.

Em seguida, a pergunta migra para: Qual é a matriz de transformação homogênea para minha mudança de base?

Para responder a isso, precisamos primeiro das respostas para três perguntas subsidiárias:

  1. Para onde minha origem se mudou?
  2. O que aconteceu com o meu eixo X? Sejam (M11, M12) as coordenadas do ponto
  3. O que aconteceu com o meu eixo Y?

Defina as respostas para estas três perguntas da seguinte forma:

  1. (M31, M32) são as coordenadas da nova origem no sistema de coordenadas original.
  2. (M11, M12) são as coordenadas do novo vetor x da unidade no sistema de coordenadas original.
  3. (M21, M22) são as coordenadas do novo vetor y da unidade no sistema de coordenadas original.

Então a matriz de transformação homogênea é:

( M11, M12,  0 )
( M21, M22,  0 )
( M31, M32,  1 )

Minha convenção aqui é que os pontos são representados por vetores de linha, que é a convenção normal de computação gráfica; os matemáticos e físicos costumam usar o opsoso.

Pieter Geerkens
fonte
Um sistema de coordenadas pode ser descrito por essa matriz: M11 = Xaxis.X, M12 = Xaxis.Y, M21 = Yaxis.X, M22 = Yaxis.Y, M31 = origem.X, M32 = origem.Y. Dada uma matriz de sistema de coordenadas A e uma matriz de sistema de coordenadas B, P * A * Inversa (B), onde P é a representação de um ponto como coordenadas em A, produz a representação do ponto como coordenadas em B.
Jim Balter