Para obter algumas informações básicas, estou tentando criar um algoritmo rápido de geração de quadtree usando uma pesquisa de dicionário. O conceito básico envolve o mapeamento de coordenadas para nós quadtree via representação binária:
struct vec2 { // Test coordinate object
double x, y; // replacing double with signed int everywhere does not achieve results either
vec2(const double& x = NULL, const double& y = NULL)
: x(x), y(y) {}
friend std::ostream& operator<<(std::ostream& os, vec2 vector)
{
return os << "(" << vector.x << ", " << vector.y << ")\n";
}
bool operator()(const vec2& lhs, const vec2& rhs) const
{
/* TODO: make proper sorting function */
if ((lhs.x < rhs.x) && (lhs.y < rhs.y)) {
return true;
}
if (std::hypot(lhs.x, lhs.y) < std::hypot(rhs.x, rhs.y)) {
return true;
}
return false;
}
};
std::map<vec2, std::bitset<4>, vec2> nodeLoc = { // quadtree node mapping
{ ( 1, 1), 1000 }, // first quadrant
{ (-1, 1), 0100 }, // second quadrant
{ (-1,-1), 0010 }, // third quadrant
{ ( 1,-1), 0001 }, // fourth quadrant
{ ( 0, 0), 0000 },
{ ( 0, 1), 1100 }, // first and second
{ ( 0,-1), 0011 }, // third and fourth
{ ( 1, 0), 1001 }, // first and fourth
{ (-1, 0), 0110 }, // second and third
};
int main() {
std::cout << nodeLoc[(-1, -1)];
return 0;
}
A função principal deve ser impressa 0010
no console, mas, 1000
em vez disso, é impressa. A função map está se identificando (-1, -1)
com (1, 1)
, mas pensei que a definição para the bool operator()
impediria que eles fossem identificados como a mesma entrada. Tentei criar uma função de hash para usar com um std::unordered_map
, mas acabei com um problema semelhante (embora um pouco diferente, pois (-1,1)
mapearia o mesmo (1,-1)
que).
Como posso criar adequadamente um mapa entre coordenadas assinadas e sua representação de nó binário?
Um compilador pode apontar dois erros cruciais no seu código:
Não há referências nulas
Em primeiro lugar, o que você está fazendo está essencialmente
const double& x = 0
nesse código. Não existe referência nula em C++, o que parece ser o que você está tentando criar. Também não que aconst&
possa se vincular a um valor temporário (materialização temporária), para que o código seja compilado.Para resolver isso, exclua o construtor completamente, o que cria
vec2
um tipo agregado. Alternativamente:(1, 1)
é uma expressão de vírgula, não uma chamada de construtorO segundo erro é usar esta sintaxe:
(1, 1)
não está fazendovec2(1, 1)
, está usando o operador vírgula, onde a esquerda1
é descartada e a direita1
é usada para chamarvec2(1)
. Seu construtor original pode ser chamado com apenas um argumento e não éexplicit
, portanto, uma conversão implícita de1
paravec2
foi possível.Para corrigir isso, use
{ { 1, 1}, 1000 }
, onde inner{ 1, 1}
é equivalente avec2(1, 1)
.Outras notas
1000
é um literal decimal; você deve fornecer um literal binário0b1000
ao inicializar umstd::bitset
vec2
não deve ser o objeto de função fornecido parastd::map
; você pode simplesmente transformaroperator()
eoperator<
usarstd::map<vec2, std::bitset<4>>
nodeLoc
deve ser declaradoconst
idealmente e, em vez denodeLoc[(x, y)]
(que também usa o operador vírgula), escrevanodeLoc.at({x, y})
Veja o exemplo ao vivo no Compiler Explorer com todas as alterações implementadas