Skip to content

Commit

Permalink
Atan2 (#51)
Browse files Browse the repository at this point in the history
* update function to use atan2
  • Loading branch information
Beakerboy authored May 16, 2024
1 parent b87b26c commit 488f110
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 26 deletions.
25 changes: 4 additions & 21 deletions src/building.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class Building {
}

/**
* translate all lat/log values to cartesian and store in an array
* build an array of all the lat/long values of the nodes
*/
static buildNodeList(fullXmlData) {
const nodeElements = fullXmlData.getElementsByTagName('node');
Expand All @@ -115,11 +115,12 @@ class Building {
}

/**
*
* convert all the longitude latitude values
* to meters from the home point.
*/
repositionNodes() {
for (const key in this.nodelist) {
this.nodelist[key] = Building.repositionPoint(this.nodelist[key], this.home);
this.nodelist[key] = BuildingShapeUtils.repositionPoint(this.nodelist[key], this.home);
}
}

Expand Down Expand Up @@ -261,24 +262,6 @@ class Building {
return true;
}

/**
* Rotate lat/lon to reposition the home point onto 0,0.
*/
static repositionPoint(latLon, home) {
const R = 6371 * 1000; // Earth radius in m
const circ = 2 * Math.PI * R; // Circumference
const phi = 90 - latLon[1];
const theta = latLon[0] - home[0];
const thetaPrime = home[1] / 180 * Math.PI;
const x = R * Math.sin(theta / 180 * Math.PI) * Math.sin(phi / 180 * Math.PI);
const y = R * Math.cos(phi / 180 * Math.PI);
const z = R * Math.sin(phi / 180 * Math.PI) * Math.cos(theta / 180 * Math.PI);
const abs = Math.sqrt(z**2 + y**2);
const arg = Math.atan(y / z) - thetaPrime;

return [x, Math.sin(arg) * abs];
}

/**
* Get the extents of the top level building.
*
Expand Down
37 changes: 32 additions & 5 deletions src/extras/BuildingShapeUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,25 +243,30 @@ class BuildingShapeUtils extends ShapeUtils {
}

/**
* Calculate the angle of each of a shape's edge
* Calculate the angle of each of a shape's edge.
* the angle will be PI > x >= -PI
*
* @param {THREE.Shape} shape - the shape
*
* @return {[number, ...]} the angles in radians.
*/
static edgeDirection(shape) {
const points = shape.extractPoints().shape;
points.push(points[0]);
const angles = [];
var p1;
var p2;
for (let i = 0; i < points.length - 1; i++) {
p1 = points[i];
p2 = points[i + 1];
angles.push(Math.atan((p2.y - p1.y) / (p2.x - p1.x)));
let angle = Math.atan2((p2.y - p1.y), (p2.x - p1.x));
if (angle >= Math.PI / 2) {
angle -= Math.PI;
} else if (angle < -Math.PI / 2) {
angle += Math.PI;
}
angles.push(angle);
}
p1 = points[points.length - 1];
p2 = points[0];
angles.push(Math.atan((p2.y - p1.y) / (p2.x - p1.x)));
return angles;
}

Expand Down Expand Up @@ -328,5 +333,27 @@ class BuildingShapeUtils extends ShapeUtils {
}
return angle;
}

/**
* Rotate lat/lon to reposition the home point onto 0,0.
*
* @param {[number, number]} lonLat - The longitute and latitude of a point.
*
* @return {[number, number]} x, y in meters
*/
static repositionPoint(lonLat, home) {
const R = 6371 * 1000; // Earth radius in m
const circ = 2 * Math.PI * R; // Circumference
const phi = 90 - lonLat[1];
const theta = lonLat[0] - home[0];
const thetaPrime = home[1] / 180 * Math.PI;
const x = R * Math.sin(theta / 180 * Math.PI) * Math.sin(phi / 180 * Math.PI);
const y = R * Math.cos(phi / 180 * Math.PI);
const z = R * Math.sin(phi / 180 * Math.PI) * Math.cos(theta / 180 * Math.PI);
const abs = Math.sqrt(z**2 + y**2);
const arg = Math.atan(y / z) - thetaPrime;

return [x, Math.sin(arg) * abs];
}
}
export {BuildingShapeUtils};

0 comments on commit 488f110

Please sign in to comment.