Y e X - Estou fazendo errado?


8

Às vezes, encontro problemas pequenos ao fazer meus projetos JavaScript. Isso ocorre porque a maioria das funções integradas do JavaScript executa X, Y se forem necessárias posições. (Naquela ordem).

Mas quando eu construo uma matriz 2D, começo com Y, parece mais lógico para mim executar o eixo X horizontal. Se eu sou mau em explicar, deixe-me mostrar-lhe:

insira a descrição da imagem aqui

Então, meus loops ficam assim:

for(var y = 0; y < 10; y++){
    for(var x = 0; x < 10; x++){
        console.log("Doh!");
    }
}

Isso é tão insano? Gostaria de me converter à prática normal, para que eu tenha mais facilidade ao construir meu jogo e não precise fazer alternâncias constantes.

Então, por que é X antes de Y?

Edit: Aqui está outro exemplo, e provavelmente o principal motivo da minha confusão: X é Horizontal e Y é Vertical em meus livros.

[
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
[0,1,2,3,4],
]

3
Meu primeiro instinto seria porque rotulamos pontos como (X, Y) em um plano cartesiano.
Vaughan Empunhaduras

Acho que sim, mas olhe para o meu novo exemplo de matriz. Parece-me mais certo dessa maneira #
Oliver Schöning ''

Respostas:


8

Não, se está funcionando para você, você não está fazendo errado. Se você quiser mudar, faça isso. A ordem em que você processa linhas / colunas às vezes é arbitrária, às vezes não. A ordem que você usa depende inteiramente do algoritmo que você está usando.

Existem várias combinações diferentes para o processamento de X, Y. Cabe a você escolher qual é o correto para o seu algoritmo. No caso em que cada iteração é independente de qualquer outra, você pode escolher qual desejar. Você pode alternar entre o loop interno e também se os loops vão de min para max ou max para min.

Eu imagino que o padrão é:

for xmin to xmax
    for ymin to ymax

porque é assim que os dados são organizados na memória. (Não necessariamente verdadeiro para todos os idiomas, pois a ordem do índice pode mudar).

Por exemplo, uma matriz A[3][3]( A[X][Y]):

insira a descrição da imagem aqui

Onde o yvalor está no loop interno, primeiro é incrementado e depois "passa o mouse" para aumentar o xvalor. Fora isso, (X, Y) é a maneira padrão de escrevê-lo em matemática.


Cheers, bem que apenas "parece certo" quando eu estou construindo um Grid:
Oliver Schöning

4

Você está fazendo errado ... mais ou menos. A coisa errada que você está fazendo é correlacionar a ordem na qual as coordenadas são escritas com a ordem na qual os loops são aninhados. Essas são idéias totalmente diferentes!

Mais especificamente, a coisa errada é que seu sistema de coordenadas está vinculado de uma maneira forte (e quebradiça) à sua implementação do armazenamento de dados. Isso significa que você está criando um código incorreto do ponto de vista de OO. O armazenamento de dados deve ser opaco para o que o usa e o que o usa não deve se importar com o modo como os dados são armazenados. O usuário dos dados precisa apenas saber como obter as informações que deseja.

O que você deve fazer é encontrar uma maneira de abstrair sua estrutura de dados de matriz aninhada e ocultá-la em um método como getPoint(x,y). Então você não precisa se preocupar com qual matriz está aninhada em qual ordem. Você pode deixar sua estrutura de dados invertida exatamente como ela é, desde que seu método getter saiba primeiro encontrar a matriz y e, em seguida, buscar nela o elemento x. Mas o código que está chamando getPoint()não sabe disso. Ele só precisa conhecer as duas coordenadas em que está interessado.


Em outras palavras: "Os programas não se importam com o quão bonito é o seu código!"
Oliver Schöning

Mas há algo errado com a minha maneira de armazená-lo, além de estar de cabeça para baixo?
Oliver Schöning

Não, eu não penso assim; as outras respostas estão corretas dessa maneira. Meu argumento é apenas sobre como isso lhe causa confusão, o que deduzi do fato de que você perguntou. Se sua implementação dificulta a compreensão do código, encapsule essa estranheza por trás de uma boa interface e esqueça-a.
Seth Battin 6/03/2013

1

Isso não importa! Eu também sempre escrevo Y primeiro (parece mais natural). Quando você tem sua matriz em matriz como linhas, pode até fazer alguma otimização. Em vez disso:

for(var y=0; y<h; y++){
    for(var x=0; x<w; x++){
        m[y*w+x] = a;
    }
}

você pode usar isso:

for(var y=0; y<h; y++){
    var i = y*w;
    for(var x=0; x<w; x++, i++){
        m[i] = a;
    }
}

e evite muitas multiplicações! :)


Você poderia me dizer qual é o seu segundo exemplo? : o No JavaScript, não existem matrizes 2D "reais", você deve criar uma matriz de matrizes. Portanto, não sei se posso usar o segundo exemplo.
Oliver Schöning

Digamos, w = h = 1000. No primeiro exemplo, você está doint 1000000 multiplicações, enquanto no segundo exemplo, você está fazendo apenas 1000 multiplicações. A multiplicação é super difícil, muitas CPUs nem têm comando de multiplicação. Eles estão emulando-o com operações de adição e de bits.
Ivan Kuckir

Eu vejo. Mas eu simplesmente não me vejo fazendo essa iteração. Mina geralmente ter o seguinte aspecto: para (var y ...) {matriz [y] = [] para (var x ...) {matriz [y] [X] = a;}}
Oliver Schöning

11
Ah com certeza. Mas você está criando 1000 novos JS objetos no montão ... oh não importa, você provavelmente não estão implementando Adobe Photoshop em JS, de modo a manter usando suas iterações :)
Ivan Kuckir
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.