Apenas uma observação rápida: seu método atual é muito legível e sua função pode ser entendida instantaneamente. Algumas dessas respostas podem realizar a tarefa solicitada, mas são muito menos claras. Isso é bom se o desempenho for essencial, mas não deixe de comentar adequadamente para explicar a perda de clareza.
Mikes
3
Para continuar o comentário do @ MikeS, o desempenho só deve ser essencial em casos como esse se você já fez uma análise ou criação de perfil e identificou essa chamada como um gargalo. A manutenção supera o desempenho bruto, se estivermos falando da diferença entre 305fps e 303fps.
Phoshi
Respostas:
24
Sim , você pode simplificar isso. Primeiro, pare de chamá-los de vetores. São pontos. Vamos chamá-los A, Be C.
Então, você quer isso:
dist(A, B)< dist(A, C)
Substitua distâncias por distâncias ao quadrado e depois por produtos pontilhados (a partir da definição do comprimento euclidiano . Substitua ACpor AB + BC(agora esses são vetores reais). Expanda, simplifique, fator:
Você pode explicar como substituir a a + b b = a a + c c pela versão do produto escalar?
TravisG
2
@ TravisG Não tenho certeza do que você está perguntando. Se a sua pergunta é por que dist(A, B)²é a mesma dot(AB, AB), vem da própria definição do comprimento euclidiano .
Sam Hocevar
2
Claramente, isso simplifica matematicamente a equação, mas não necessariamente "economiza tempo do processador" para o OP. Isso resulta em mais complexidade e mais cálculos do que apenas remover a raiz quadrada das equações de distância originais.
Michaelhouse
1
Corrija-me se eu estiver errado, mas os dois produtos pontuais são 5 operações por produto pontual mais as duas subtrações vec3, que são um total de 16 operações, seu caminho tem 3 substrações vec3 mais uma adição que faz 12 operações mais o produto pontual faz 17.
Luis W
2
Curiosamente, o resultado é o produto escalar das duas diagonais opostas de um paralelogramo. Mas isso é irrelevante. O que eu queria dizer é que não há muito a ganhar com essa simplificação completa ; como outros já mencionaram, é uma quantia decente ofuscar ou complicar o que você está realmente tentando calcular. No entanto, você definitivamente deseja usar o primeiro passo. Evitar uma raiz quadrada desnecessária sempre vale a pena. Apenas comparar os Quadrados das distâncias é o mesmo, pois a distância é positiva definida, mesmo no plano complexo.
precisa saber é o seguinte
16
Sim. Supondo que sua distancefunção use uma raiz quadrada, você pode simplificar isso removendo a raiz quadrada.
Ao tentar encontrar a maior (ou menor) distância, x^2 > y^2ainda é válido para x > y.
No entanto, outras tentativas de simplificar matematicamente a equação provavelmente não fazem sentido. A distância entre vector1e vector2não é a mesma que distância entre vector1e vector3. Embora a equação possa ser simplificada matematicamente, como mostra a resposta de Sam , a forma em que está atualmente é provavelmente tão simples quanto você obterá da perspectiva de uso do processador.
Não tenho representante suficiente, mas, como fundamentalmente incorreto, acredito: "posso economizar tempo de processador simplificando essa desigualdade?" A resposta é sim.
Eu estou tão confuso
A resposta é apenas sim se a equação da distância estiver usando uma raiz quadrada. O que eu mencionei.
MichaelHouse
Ponto válido, eu retiraria minha declaração. No entanto, é 99% garantido que o usuário significa sqrt distância euclidiana (soma (diferenças dimensionais quadrado))
im tão confuso
@imsoconfused Fair bastante, eu mudei a ordem da minha resposta para indicar o cenário mais provável (99%) primeiro.
MichaelHouse
2
Sim, minha experiência é quando você lida com esse tipo de coisa, uma função DistanceSquared é muito útil. É igualmente claro e evita a operação cara do sqrt.
A verdadeira questão parece ser como reduzir a computação para determinar o objeto mais próximo?
A otimização disso geralmente é feita em jogos, embora com todas as otimizações deva ser guiada por perfil e, muitas vezes, não simplifica as coisas.
A maneira de evitar cálculos de distância desnecessários para determinar a coisa mais próxima - ou todas as coisas dentro de um determinado intervalo - é usar um índice espacial, por exemplo, uma octree .
Isso só compensa se houver um grande número de objetos. Por apenas três objetos, é improvável que valha a pena e certamente não simplifica o código.
Eu acho que a pergunta real é bastante direta, e esta resposta não aborda isso. Se você quiser especular sobre as questões mais profundas e não declaradas do OP, isso deve ser feito como um comentário, se você realmente não responder à pergunta.
Estou com o voto negativo porque invocar uma possível otimização prematura não é uma resposta para um problema em que a otimização explícita não prejudica a legibilidade, a manutenção do código nem incentiva práticas obscuras. Quando você pode escrever um código simples e otimizado, por que não fazê-lo? Certamente não custa nada, mesmo se você tiver um plano de nível superior (nenhum desenvolvedor de jogos jamais recusará alguns microssegundos extras por quadro, especialmente nos consoles).
Teodron #
@teodron: "Quando você pode escrever um código simples e otimizado, por que não fazê-lo?" - Porque o OP (e agora nós) passou um tempo não negligenciável otimizando algo que pode não lhe proporcionar nenhum benefício.
BlueRaja # Danny Pflughoeft
@ BlueRaja-DannyPflughoeft Eu concordo que isso seja menor (portanto, otimização insignificante se usada para algumas centenas de chamadas por quadro, mas se o fator de magnitude aumentar para milhares, as coisas certamente mudam). No entanto, somos todos livres para não perder tempo tentando responder / otimizar algo que consideramos inviável. O OP pediu uma coisa: as pessoas supuseram que o OP não estava ciente das estratégias e práticas de criação de perfil de nível superior. Pessoalmente, prefiro fazer essas observações nos comentários, não nas respostas. Desculpe por ser tão detalhado :(.
teodron
-3
depende de qual é a saída da distância (v1, v2)
se for um decimal (flutuante ou duplo) sobre um vetor, é provável que a distância percorrida seja muito mais rápida
i significou um flutuador sobre outro vector só não explicou muito bem (e eu acho que você sabia disso)
RoughPlace
5
Eu não estava intencionalmente mal-entendido. Ainda não tenho certeza do que você quer dizer. Não sei por que uma função de distância retornaria um vetor.
Respostas:
Sim , você pode simplificar isso. Primeiro, pare de chamá-los de vetores. São pontos. Vamos chamá-los
A
,B
eC
.Então, você quer isso:
Substitua distâncias por distâncias ao quadrado e depois por produtos pontilhados (a partir da definição do comprimento euclidiano . Substitua
AC
porAB + BC
(agora esses são vetores reais). Expanda, simplifique, fator:Aí está você:
Com sua notação vetorial:
São algumas adições e um produto de ponto em vez dos dois produtos de ponto anteriores.
fonte
dist(A, B)²
é a mesmadot(AB, AB)
, vem da própria definição do comprimento euclidiano .Sim. Supondo que sua
distance
função use uma raiz quadrada, você pode simplificar isso removendo a raiz quadrada.Ao tentar encontrar a maior (ou menor) distância,
x^2 > y^2
ainda é válido parax > y
.No entanto, outras tentativas de simplificar matematicamente a equação provavelmente não fazem sentido. A distância entre
vector1
evector2
não é a mesma que distância entrevector1
evector3
. Embora a equação possa ser simplificada matematicamente, como mostra a resposta de Sam , a forma em que está atualmente é provavelmente tão simples quanto você obterá da perspectiva de uso do processador.fonte
Algumas matemáticas podem ajudar.
O que você está tentando fazer é:
Pelo que você pode remover variáveis repetidas e agrupar outras. A operação que você precisa verificar é:
Espero que ajude.
fonte
A verdadeira questão parece ser como reduzir a computação para determinar o objeto mais próximo?
A otimização disso geralmente é feita em jogos, embora com todas as otimizações deva ser guiada por perfil e, muitas vezes, não simplifica as coisas.
A maneira de evitar cálculos de distância desnecessários para determinar a coisa mais próxima - ou todas as coisas dentro de um determinado intervalo - é usar um índice espacial, por exemplo, uma octree .
Isso só compensa se houver um grande número de objetos. Por apenas três objetos, é improvável que valha a pena e certamente não simplifica o código.
fonte
depende de qual é a saída da distância (v1, v2)
se for um decimal (flutuante ou duplo) sobre um vetor, é provável que a distância percorrida seja muito mais rápida
fonte
float
tem a ver com nada.