WorldToCameraImageCoords
This document introduces two overloaded functions that project 3D world points into 2D camera image coordinates using a pinhole camera model.
Function Signatures
1. Explicit Look‑At Projection
Eigen::MatrixX2d WorldToCameraImageCoords(
    const Eigen::MatrixX3d& targetVertices,
    const Eigen::RowVector3d& cameraDirPoint,
    const Eigen::RowVector3d& cameraPosition,
    double FL
);
2. Centroid‑Based Projection
Eigen::MatrixX2d WorldToCameraImageCoords(
    const Eigen::MatrixX3d& targetVertices,
    const Eigen::RowVector3d& cameraPosition,
    double FL
);
Parameters
- targetVertices: 
Eigen::MatrixX3d, where each row is a 3D point to project. - cameraDirPoint: 
Eigen::RowVector3d, specifying the point the camera looks at (only for overload 1). - cameraPosition: 
Eigen::RowVector3d, representing the camera’s position in world coordinates. - FL: 
doublefocal length of the pinhole camera. 
Return Value
Eigen::MatrixX2d: A matrix of size(N×2), where each row is the projected 2D image coordinate(u, v)corresponding to an input vertex.
Example Usage
1. Prepare Input Data
Define a cuboid using eight corner points in world coordinates. Also specify the camera’s position, look‑at point, and focal length:
Eigen::Matrix<double,8,3> testTarget;
testTarget << 748793.66839939367, 2565000.6052587116, 48.909999999999997,
    748791.82177844818, 2565003.9931349289, 48.909999999999997,
    748795.20965466544, 2565005.8397558741, 48.909999999999997,
    748797.05627561093, 2565002.4518796569, 48.909999999999997,
    748793.66839939367, 2565000.6052587116, 50.909999999999997,
    748791.82177844818, 2565003.9931349289, 50.909999999999997,
    748795.20965466544, 2565005.8397558741, 50.909999999999997,
    748797.05627561093, 2565002.4518796569, 50.909999999999997;
Eigen::RowVector3d cameraPosition(748780.10705481586, 2565024.6238759784, 57.51);
Eigen::RowVector3d cameraDirPoint(748794.43902702956, 2565003.2225072929, 49.909999999999997);
double FL = 32.0;
2. Perform 3D-to-2D Projection
Eigen::Matrix<double, 8, 2> imagePoints = WorldToCameraImageCoords(testTarget, cameraDirPoint, cameraPosition, FL);
3. Result
The projected 2D image coordinates are visualized below:
The red rectangle in the image represents the assumed CMOS sensor area of the camera, with a physical size of 6.4 mm × 4.8 mm.
Complete Implementation
#include "LiteGeometry.h"
int main() {
    Eigen::Matrix<double,8,3> testTarget;
    testTarget << 748793.66839939367, 2565000.6052587116, 48.909999999999997,
        748791.82177844818, 2565003.9931349289, 48.909999999999997,
        748795.20965466544, 2565005.8397558741, 48.909999999999997,
        748797.05627561093, 2565002.4518796569, 48.909999999999997,
        748793.66839939367, 2565000.6052587116, 50.909999999999997,
        748791.82177844818, 2565003.9931349289, 50.909999999999997,
        748795.20965466544, 2565005.8397558741, 50.909999999999997,
        748797.05627561093, 2565002.4518796569, 50.909999999999997;
    Eigen::RowVector3d cameraPosition(748780.10705481586, 2565024.6238759784, 57.51);
    Eigen::RowVector3d cameraDirPoint(748794.43902702956, 2565003.2225072929, 49.909999999999997);
    double FL = 32.0;
    std::cout << "Camera Position: " << cameraPosition.format(Eigen::FullPrecision) << "\n";
    std::cout << "Camera Look-at Point: " << cameraDirPoint.format(Eigen::FullPrecision) << "\n";
    std::cout << "Focal Length: " << FL << "\n";
    Eigen::Matrix<double, 8, 2> imagePoints = WorldToCameraImageCoords(testTarget, cameraDirPoint, cameraPosition, FL);
    std::cout << "\nProjected Image Coordinates:\n";
    std::cout << imagePoints.format(Eigen::FullPrecision) << "\n";
    return 0;
}