Wednesday, May 8, 2024
HomeGame Developmentshaders - How to calculate a direction vector from a 3x3 rotation...

shaders – How to calculate a direction vector from a 3×3 rotation matrix?


been stuck with the following problem and can’t seem to find any solution. I’ll appreciate the help a lot.

I have a dataset containing 2d images of telco towers and metadata. Each 2d image has 3×3 rotation matrix which provides orientation info about the drone when it captured the image.

Now I have a 3d site(tower) constructed in threejs canvas with z in up direction and camera looking in y direction, containing multiple annotation bounding boxes. Whenever one clicks on a bounding box on tower, we want best view 2d images filtered from our dataset relative to our pov of the asset in bounding box on tower. Which is not the case right now.

Right now I’m extracting third row from our 3×3 rotation matrix and checking the angle between that vector and threejs camera direction vector in world space.

One solution I thought was to use camera.worldInverseMatrix and get the direction vector of camera in view space. Only then i compare the updated direction vector with the direction vector extracted from rotation matrix of 2d image. But I don’t exactly know how to implement this.

Lemme know if you have any questions and I’d love to answer them. But any help would be great!

bestViewImages(imgsWithRotationAndCenter: any[], cameraPosition: any, cameraDirection: any, angleThresholdDegrees: number,
distThreshMeters: number, numViewsToReturn: number) {
let angleFilteredImages: any[] = [];
let filteredImagesToDistance: any = {};

for (const image of imgsWithRotationAndCenter) {
  let isRotationMatrixExists: boolean = !!(image?.rotationMatrix.length);
  if (isRotationMatrixExists) {
    console.log('rotation matrxix: ', image.rotationMatrix)
    let directionVector: ICameraAxis = {
      'x': image.rotationMatrix[2][0],
      'y': image.rotationMatrix[2][1],
      'z': image.rotationMatrix[2][2]
    }

    if (this.checkIfAngleBetweenVecsIsWithinThreshold(directionVector, cameraDirection, angleThresholdDegrees)) {
      angleFilteredImages.push(image);
    }
  }
}

for (let idx: number = 0; idx < angleFilteredImages.length; idx += 1) {
  let isCameraCenterExists: boolean = !!(imgsWithRotationAndCenter[idx]?.cameraCenter.length);
  if (isCameraCenterExists) {
    let imageCameraCenter: ICameraAxis = {
      'x': angleFilteredImages[idx].cameraCenter[0],
      'y': angleFilteredImages[idx].cameraCenter[1],
      'z': angleFilteredImages[idx].cameraCenter[2]
    }
    let dis: number = this.calculateDistanceBetween3DPoints(imageCameraCenter, cameraPosition);
    if (dis < distThreshMeters) {
      filteredImagesToDistance[angleFilteredImages[idx]?.imageName] = dis;
    }
  }
}

let distanceBasedSortedImages: String[] = !this.commonService.isObjectEmpty(filteredImagesToDistance) ? this.sortDictionary(filteredImagesToDistance) : [];
// let topFiveImages = (distanceBasedSortedImages.length) ? distanceBasedSortedImages.slice(0, numViewsToReturn) : [];
console.log('distanceBasedSortedImages: ', distanceBasedSortedImages)
return distanceBasedSortedImages;

}

private checkIfAngleBetweenVecsIsWithinThreshold(vec1: ICameraAxis, vec2: ICameraAxis, threshDegrees: number) {
    let dotProduct = vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
    let vec1Mag = Math.sqrt(vec1.x * vec1.x + vec1.y * vec1.y + vec1.z * vec1.z);
    let vec2Mag = Math.sqrt(vec2.x * vec2.x + vec2.y * vec2.y + vec2.z * vec2.z);
    let cosTheta = (dotProduct / (vec1Mag * vec2Mag));
    let angle = Math.acos(cosTheta) * (180 / Math.PI);
    return (angle < threshDegrees) ? true : false;
}


private calculateDistanceBetween3DPoints(point1: ICameraAxis, point2: ICameraAxis) {
    return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2) + Math.pow(point2.z - point1.z, 2));
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments