Pergunta

Ok, isso é algo que deve ser uma pergunta simples matriz, mas o meu entendimento de matrizes é um pouco limitado. Aqui está o cenário: Eu tenho um 1 x 1 pixel sprite que eu quero escala por alguns montante xey (quantidades diferentes de cada lado), e depois quero rodar que Sprite por algum ângulo, e então eu quero ser capaz de posicionar precisamente a coisa toda (do topo para a esquerda ou ao centro, não faz diferença para mim).

Até agora o meu código é vagamente perto, mas ela tende a estar fora por alguma quantidade aleatória, dependendo do ângulo que eu passar em.

Gostaria de pensar que isso iria fazê-lo:

        Point center = new Point( 50, 50 );
        float width = 60;
        float height = 100;
        float angle = 0.5;
        Vector3 axis = new Vector3( center.X, center.Y, 0 );
        axis.Normalize();
        Matrix m = Matrix.Scaling( width, height, 0 ) *
            Matrix.RotationAxis( axis, angle ) *
            Matrix.Translation( center.X, center.Y, 0 );

Mas ele tende a diminuir a escala da linha de caminho rodada, mesmo que eu acho que está posicionando-tipo de direito.

Eu também tentei isso:

  Matrix m = Matrix.Transformation2D( new Vector2( center.X, center.Y ), 0f,
      new Vector2( width, height ), new Vector2( center.X, center.Y ),
      angle, Vector2.Zero );

Os olhares linha exatamente certo, com o tamanho ea forma exata certo, mas eu não pode posicioná-lo corretamente em tudo. Se eu usar o vetor de translação no final da chamada acima, ou se eu definir uma posição usando Sprite.Draw, nem funciona direito.

Esta é tudo em SlimDX. O que estou fazendo de errado?

Foi útil?

Solução

Eu só fui com a dor de aprender transformação de matriz, mas usando XNA.

estes artigos para ser muito útil para compreender o que acontece. As chamadas de método são muito semelhantes em XNA e a teoria por trás de tudo deve se aplicar a você, mesmo com SlimDX.

A partir de olhar para o seu código, eu acho que você deve ser a tradução no início, a origem, e depois traduzir novamente no final, para a posição final, embora eu ainda sou um pouco de um novato para isso como bem.

A ordem que eu iria fazê-lo em é:

  • Traduzir para origem
  • Escala
  • Girar
  • Traduzir para o local desejado

A razão para traduzir a origem primeira é que rotações são baseadas a partir da origem . Portanto, para algo girar sobre um determinado ponto, lugar que ponto sobre a origem antes de girar.

Outras dicas

A aprovação, esta está agora a trabalhar. Aqui está o meu código trabalhando para isso, nas necessidades de outra pessoa caso de alguém que:

    Point sourceLoc = new Point ( 50, 50 );
    float length = 60;
    float thickness = 2;
    float angle = 0.5;
    Matrix m = Matrix.Scaling( length, thickness, 0 ) *
            Matrix.RotationZ( angle ) *
            Matrix.Translation( sourceLoc.X, sourceLoc.Y, 0 );
    sprite.Transform = m;

    sprite.Draw( this.tx, Vector3.Zero, Vector3.Zero, Color.Red );

Isto irá desenhar uma linha angular do seu comprimento escolhido, com uma espessura igual à sua espessura escolhida (presumindo a sua textura é um pixel 1x1 imagem branca). O local de origem é onde a linha irá emitir a partir de, com qualquer ângulo que você especifique (em radianos). Então, se você começar a zero e incremento por algo como 0,1 até chegar 2PI, e depois repor a 0, você vai ter uma linha que gira em torno de um centro como uma mão relógio ou varredura radar. Isto é o que eu estava procurando - graças a todos os que contribuíram

Você está girando em torno do eixo correto? Eu sou um novato no material de matriz, mas parece-me que desde que existe o sprite na x, y espaço, o eixo de rotação deve ser o Z-Axis - ou seja, (0,0,1).

O que você precisa fazer é fazer cada transformação um passo de cada vez. Faça o escalonamento primeira desenhá-lo. É onde você espera. Em seguida, jogar à girar, e então a traduzir. Isso ajudará suposições uncover incorretas.

Você também pode desenhar em linhas temporárias para ajuda figura, onde as coordenadas são. Por exemplo, se você faz o seu alongamento e rotação e esperar que o seu ponto final para ser em 0,0. Desenhando uma outra linha com um ponto final em 0,0 servirá como uma segunda verificação para ver se isso realmente o caso.

Para o seu problema específico o problema pode estar com a rotação. Depois de ter escalado e girar a linha está agora fora do centro causando-lhe problemas quando você está traduzindo.

A solução geral é para mover a linha de volta à origem fazer quaisquer operações que envolvem mudando-lhe forma ou orientação. Depois porque você está em um local conhecido bom você pode traduzir para o seu destino final.

resposta aos comentários

Se a tradução é um problema e você estão transformando o sistema de coordenadas, então você terá que escrever uma função de conversão para converter entre o sistema antigo eo novo.

Por exemplo, se você está girando 45 graus. Antes da rotação você poderia traduzir por 0,1 para subir de 1 polegada. Depois de rotação você terá que traduzir em cerca de -.70707, 0,070707 para subir de 1 polegada em relação ao original sistema de coordenadas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top