Check if position is between 2 positions

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 too 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;
}
    
asked by anonymous 25.10.2016 / 12:21

1 answer

1

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

Change your HashMap String key to HashMap Integer key, in the hashmap key use hashcode of your Region _ object, in getRegion method you can make a search directly for the hash, it is not necessary to make a for if min and max are equivalent.

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

Follow my idea of solution, there are other approaches to search optimization, I tried not to break the compatibility of your code very 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;
    }

}

}

    
25.10.2016 / 14:03