Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ordered Neighbours #10

Open
AaronGaddes opened this issue Feb 6, 2021 · 2 comments
Open

Ordered Neighbours #10

AaronGaddes opened this issue Feb 6, 2021 · 2 comments

Comments

@AaronGaddes
Copy link

AaronGaddes commented Feb 6, 2021

Hi There. Firstly I'd like to say that this is a nifty project;

I am currently trying to build a little game which uses this library to create the game world. However I have run into an issue where I need the neighbours to be in the same order as the boundary points so that I am able to determine what tile is in a particular direction from the current tile.

Any chance that would be something you would be able to add into the library? I have tried making changes to a local copy of the library myself by using the face index as a kind of sorting key to the neighborHash but that didn't seem to work:

// tile.js
    var neighborHash = {};
    for(var f=0; f< this.faces.length; f++){
        // build boundary
        this.boundary.push(this.faces[f].getCentroid().segment(this.centerPoint, hexSize));

        // get neighboring tiles
        var otherPoints = this.faces[f].getOtherPoints(this.centerPoint);
        for(var o = 0; o < 2; o++){
            neighborHash[otherPoints[o]] = f;
        }

    }

    this.neighborIds = Object.entries(neighborHash).sort(([n1, f1], [n2, f2]) => f1 - f2).map(([n])=> n);
@caramboleyo
Copy link

The problem for this is here:

var otherPoints = this.faces[f].getOtherPoints(this.centerPoint);

It creates the boundary by walking it point by point. For every point it determines the two other adjacent tiles, which border this point. Problem is here, that sometimes those two tiles come in reverse order. So although the boundary is being walked in correct order, some pairs are twisted. Because it is not walking the edges, but the corner points. While the edges would always have only one neighbor tile, the points have two.

Example: the boundary is along tiles with index 274 268 153 152 but those points return 268 274 152 153. The last two are twisted.

My quick hack for this is cashing it in a prev array and a first var to maintain order, surely @arscan will have a more elegant solution:

		const neighborHash = {};
		let prev = [];
		let first = null;
		for (var f = 0; f < this.faces.length; f++) {
			const p = this.faces[f].getCentroid().segment(this.centerPoint, hexSize);
			// build boundary
			this.boundary.push(p);

			// get neighboring tiles
			const otherPoints = this.faces[f].getOtherPoints(this.centerPoint);
			if (prev.includes(otherPoints[0])) {
				neighborHash[otherPoints[0]] = 1;
				if (first === null) {
					first = prev[prev.indexOf(otherPoints[0]) === 0 ? 1 : 0];
				}
			}
			if (prev.includes(otherPoints[1])) {
				neighborHash[otherPoints[1]] = 1;
				if (first === null) {
					first = prev[prev.indexOf(otherPoints[1]) === 0 ? 1 : 0];
				}
			}
			prev = otherPoints;
		}
		neighborHash[first] = 1;

		this.neighborIds = Object.keys(neighborHash);

@caramboleyo
Copy link

My solution still leaves one case where first and last seem to be twisted :'(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants