Check if position is between 2 positions

Asked

Viewed 111 times

1

I am using this code here to check if a position is 'inside' an 'area', but it will probably explode if the hashmap has many Keys/Values, what would be the best way to do this ? Thank you.

HashMap<String, Region_> regionsHash = new HashMap<String, Region_>();
public class Region_ {
    public Region_ (vector _minPos, vector _maxPos){
        minPos = _minPos;
        maxPos = _maxPos;
    }

    vector minPos;
    vector maxPos;
}

class vector{
    vector (int _X, int _Y,int _Z){
        X = _X;
        Y = _Y;
        Z = _Z;
    }
    int X, Y, Z;
}

String getRegion (vector _vector3D){
    for (String regionKey : regionsHash.keySet()) {
        Region_ region = regionsHash.get(regionKey);

        if(region.maxPos.X >= _vector3D.X && region.maxPos.Y >= _vector3D.Y && region.maxPos.Z >= _vector3D.Z){
            if(region.minPos.X <= _vector3D.X && region.minPos.Y <= _vector3D.Y && region.minPos.Z <= _vector3D.Z){
                return regionKey;
            }
        }
    }
    return null;
}

1 answer

1

You can implement the equals and the hashcode from the positions x and y in your object Region_.

Change your HashMap string key for HashMap key to Integer, in the key of hashmap use the hashcode of your object Region_, in the method getRegion you can do a search directly for the hash, it is not necessary to perform a for where min and max are equivalent.

Any doubt, if you use eclipse, go to option generate hashcode & equals. It’s worth putting one breakpoint in these methods to see how it behaves.

Follow my solution idea, there are other search optimization approaches, I tried not to break the compatibility of your code too much. Anything gives a touch.

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class BuscaGrafica {

Map<Integer, Region_> regionsHash = new HashMap<>();

void addRegion(Region_ region) {
    /**
     * Internamente ele vai guardar na posição de memória referente ao region.hashCode()
     * XXX Tem que ter atenção com este método, pois utilizando o hashCode como chave significa
     * que os elementos não poderão ser alterados, pois uma vez que eu alterar fará com
     * que o hashcode não seja mais o mesmo e o elemento de perca na memória.
     */
    regionsHash.put(region.hashCode(), region);
}

Region_ getRegion(vector _vector3D) {
    Region_ r = new Region_(_vector3D, _vector3D);
    // Otimização para procurar uma posição onde o minPos e maxPos sejam equivalentes
    if (regionsHash.containsKey(r)) {
        // A busca é instantânea não gera muito custo computacional
        regionsHash.get(r);
    } else {
        /**
         * Aqui não tem muito milagre, o cara vai ter que procurar na mão
         * Sugestões para aprimoramento desta rotina, poderá ser utilizado uma estrutura de dados
         * onde a ordenação dos elementos seja por ordem de grandeza
         * sendo assim podemos utilizar um algoritmo inteligente, que não precise percorrer todos os elementos do array.
         * Ficar atendo que o retorno pode ser mais de um {@link Region_}, pois pode haver mais de um elemento 3d dentro de outro ainda maior.
         */
        Map<Integer, Region_> collect = regionsHash.entrySet().stream()//
                .filter(element -> (element.getValue().maxPos.X >= _vector3D.X && element.getValue().maxPos.Y >= _vector3D.Y && element.getValue().maxPos.Z >= _vector3D.Z) && //
                                   (element.getValue().minPos.X <= _vector3D.X && element.getValue().minPos.Y <= _vector3D.Y && element.getValue().minPos.Z <= _vector3D.Z))//
                .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
        // XXX aqui eu retornei o primeiro registro encontrado pelo lambda, mas é bom ficar atendo que o retorno pode ser mais de um...
        return collect.values().iterator().next();
    }
    return null;
}

public class Region_ {

    public Region_(vector _minPos, vector _maxPos) {
        minPos = _minPos;
        maxPos = _maxPos;
    }

    vector minPos;
    vector maxPos;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + getOuterType().hashCode();
        result = prime * result + ((maxPos == null) ? 0 : maxPos.hashCode());
        result = prime * result + ((minPos == null) ? 0 : minPos.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Region_ other = (Region_) obj;
        if (!getOuterType().equals(other.getOuterType())) return false;
        if (maxPos == null) {
            if (other.maxPos != null) return false;
        } else if (!maxPos.equals(other.maxPos)) return false;
        if (minPos == null) {
            if (other.minPos != null) return false;
        } else if (!minPos.equals(other.minPos)) return false;
        return true;
    }

    private BuscaGrafica getOuterType() {
        return BuscaGrafica.this;
    }

}

class vector {

    vector(int _X, int _Y, int _Z) {
        X = _X;
        Y = _Y;
        Z = _Z;
    }

    int X, Y, Z;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + getOuterType().hashCode();
        result = prime * result + X;
        result = prime * result + Y;
        result = prime * result + Z;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        vector other = (vector) obj;
        if (!getOuterType().equals(other.getOuterType())) return false;
        if (X != other.X) return false;
        if (Y != other.Y) return false;
        if (Z != other.Z) return false;
        return true;
    }

    private BuscaGrafica getOuterType() {
        return BuscaGrafica.this;
    }

}

}

  • Welcome to the stackoverlow community. Make a tour and learn a little about the rules and good practices. Make at least a demonstration of how it could be implemented, for an easy view of the answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.