Skip to content

Instantly share code, notes, and snippets.

@jo-chemla
Last active August 29, 2024 12:37
Show Gist options
  • Save jo-chemla/b25b21b4614734ac7ab8adb4e43f85f1 to your computer and use it in GitHub Desktop.
Save jo-chemla/b25b21b4614734ac7ab8adb4e43f85f1 to your computer and use it in GitHub Desktop.
computeCrsTransform by transforming trihedron via proj4
const computeCrsTransform = (
sourceCrsOriginCoords,
sourceCrsProj,
targetCrsProj
) => {
let sourceCrsDefinition =
sourceCrsProj || "+proj=longlat +datum=WGS84 +no_defs";
const targetCrsDefinition =
targetCrsProj || "+proj=longlat +datum=WGS84 +no_defs";
// Attempt to use sourceCrsProj if defined; otherwise, define and use 'sourceCRS'
let sourceCRS = proj4.defs(sourceCrsProj) ? sourceCrsProj : "sourceCRS";
if (!proj4.defs(sourceCrsProj)) {
proj4.defs(sourceCRS, sourceCrsDefinition);
}
// Attempt to use targetCrsProj if defined; otherwise, define and use 'targetCRS'
let targetCRS = proj4.defs(targetCrsProj) ? targetCrsProj : "targetCRS";
if (!proj4.defs(targetCrsProj)) {
proj4.defs(targetCRS, targetCrsDefinition);
}
const transformProj = proj4(sourceCRS, targetCRS);
// Use first scene position as origin of transformation
const originInSourceCoords = sourceCrsOriginCoords;
const originInTargetCoords = new THREE.Vector3().fromArray(
transformProj.forward(originInSourceCoords.toArray())
);
const scale = 1000;
const xVector = new THREE.Vector3().fromArray(
transformProj.forward(
originInSourceCoords
.clone()
.add(new THREE.Vector3(scale, 0, 0))
.toArray()
)
);
const yVector = new THREE.Vector3().fromArray(
transformProj.forward(
originInSourceCoords
.clone()
.add(new THREE.Vector3(0, scale, 0))
.toArray()
)
);
// Optionally compute zVector for full 3D transformation
// const zVector = new THREE.Vector3().fromArray(
// transformProj.forward(
// originInSourceCoords.clone().add(new THREE.Vector3(0, 0, scale)).toArray()
// )
// );
const ox = xVector.clone().sub(originInTargetCoords.clone());
const oy = yVector.clone().sub(originInTargetCoords.clone());
// For oz, seems like we can cross-vectors and results are almost similar
// + remove warning of non unit scale in all directions by 3dtilesrenderer
// const oz = z.clone().sub(origin_datasetCrs.clone());
// oz.divideScalar(scale);
ox.divideScalar(scale);
oy.divideScalar(scale);
const oz = new THREE.Vector3().crossVectors(ox, oy);
const rot_scene_to_dataset = new THREE.Matrix4().makeBasis(ox, oy, oz);
const rot_dataset_to_scene = rot_scene_to_dataset.clone().invert();
const trans_zeroToScene = new THREE.Matrix4().makeTranslation(
...originInSourceCoords.toArray()
);
const minus_origin_datasetCrs = originInTargetCoords
.clone()
.multiplyScalar(-1);
const trans_datasetToZero = new THREE.Matrix4().makeTranslation(
...minus_origin_datasetCrs.toArray()
);
const matrixTransform = new THREE.Matrix4()
.multiply(trans_zeroToScene)
.multiply(rot_dataset_to_scene)
.multiply(trans_datasetToZero);
return matrixTransform;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment