Skip to content

Commit

Permalink
feat: use bearings for fov visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
oscarlorentzon committed Apr 1, 2024
1 parent 56a7e73 commit 22c2154
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 28 deletions.
37 changes: 9 additions & 28 deletions src/component/bearing/BearingComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,7 @@ export class BearingComponent extends Component<BearingConfiguration> {
return [Math.PI, Math.PI];
}

const currentProjectedPoints =
this._computeProjectedPoints(transform);
const hFov = this._spatial
.degToRad(
this._computeHorizontalFov(
currentProjectedPoints));
const hFov = this._computeHorizontalFov(transform);

let hFovLeft: number = hFov / 2;
let hFovRight: number = hFov / 2;
Expand Down Expand Up @@ -469,37 +464,23 @@ export class BearingComponent extends Component<BearingConfiguration> {
]);
}

private _computeProjectedPoints(transform: Transform): number[][] {
private _computeHorizontalFov(transform: Transform): number {
const vertices: number[][] = [[1, 0]];
const directions: number[][] = [[0, 0.5]];
const pointsPerLine: number = 12;

return Geo
.computeProjectedPoints(
transform,
vertices,
directions,
pointsPerLine,
this._viewportCoords)
.map(([x, y]) => [Math.abs(x), Math.abs(y)]);
}

private _computeHorizontalFov(projectedPoints: number[][]): number {
const fovs: number[] = projectedPoints
.map(
(projectedPoint: number[]): number => {
return this._coordToFov(projectedPoint[0]);
});
const bearings = Geo.computeBearings(
transform, vertices, directions, pointsPerLine, this._viewportCoords);
const projections = bearings
.map(b => this._spatial.projectToPlane(b, [0, 1, 0]))
.map(p => [p[0], p[2]]);

const fov: number = Math.min(...fovs);
const angles = projections.map(p => Math.atan2(p[0], -p[1]));
const fov = 2 * Math.min(...angles);

return fov;
}

private _coordToFov(x: number): number {
return this._spatial.radToDeg(2 * Math.atan(x));
}

private _interpolate(x1: number, x2: number, alpha: number): number {
return (1 - alpha) * x1 + alpha * x2;
}
Expand Down
40 changes: 40 additions & 0 deletions src/geo/Geo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,46 @@ export function computeTranslation(position: LngLatAlt, rotation: number[], refe
return translation;
}

export function computeBearings(
transform: Transform,
basicVertices: number[][],
basicDirections: number[][],
pointsPerLine: number,
viewportCoords: ViewportCoords): number[][] {

// @ts-ignore
const camera: THREE.Camera = new THREE.Camera();
camera.up.copy(transform.upVector());
camera.position.copy(new THREE.Vector3().fromArray(transform.unprojectSfM([0, 0], 0)));
camera.lookAt(new THREE.Vector3().fromArray(transform.unprojectSfM([0, 0], 10)));
camera.updateMatrix();
camera.updateMatrixWorld(true);

const basicPoints: number[][] = [];
for (let side: number = 0; side < basicVertices.length; ++side) {
const v: number[] = basicVertices[side];
const d: number[] = basicDirections[side];

for (let i: number = 0; i <= pointsPerLine; ++i) {
basicPoints.push([
v[0] + d[0] * i / pointsPerLine,
v[1] + d[1] * i / pointsPerLine,
]);
}
}

const bearings: number[][] = [];
for (const [index, basicPoint] of basicPoints.entries()) {
const worldPoint = transform.unprojectBasic(basicPoint, 10000);
const cameraPoint = new THREE.Vector3()
.fromArray(viewportCoords.worldToCamera(worldPoint, camera));
cameraPoint.normalize();
bearings.push(cameraPoint.toArray());
}

return bearings;
}

export function computeProjectedPoints(
transform: Transform,
basicVertices: number[][],
Expand Down
18 changes: 18 additions & 0 deletions src/geo/Spatial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,24 @@ export class Spatial {
return Math.asin(projection / norm);
}

/**
* Calculates the projection of a vector onto a plane.
*
* @param {Array<number>} vector - The vector.
* @param {Array<number>} planeNormal - Normal of the plane.
* @returns {number} Projection of vector onto plane.
*/
public projectToPlane(vector: number[], planeNormal: number[]): number[] {
const directionVector: THREE.Vector3 = new THREE.Vector3().fromArray(vector);
const normalVector: THREE.Vector3 = new THREE.Vector3().fromArray(planeNormal);

const normalProjection: number = directionVector.clone().dot(normalVector);
const planeProjection: THREE.Vector3 = directionVector
.clone().sub(normalVector.clone().multiplyScalar(normalProjection));

return planeProjection.toArray();
}

public azimuthal(direction: number[], up: number[]): number {
const directionVector: THREE.Vector3 = new THREE.Vector3().fromArray(direction);
const upVector: THREE.Vector3 = new THREE.Vector3().fromArray(up);
Expand Down

0 comments on commit 22c2154

Please sign in to comment.