Polygon Mesh Processing page 32

An example from Polygon Mesh Processing page 32

The original equation:

placeholder

I❤️LA implementation:

from trigonometry: sin, cos
`x(θ, ϕ)` = [Rcos(θ)cos(ϕ)
             Rsin(θ)cos(ϕ)
             Rsin(ϕ)]

where

ϕ ∈ ℝ : angle between 0 and 2π
θ ∈ ℝ : angle between -π/2 and π/2
R ∈ ℝ : the radius of the sphere

I❤️LA compiled to C++/Eigen:

/*
from trigonometry: sin, cos
`x(θ, ϕ)` = [Rcos(θ)cos(ϕ)
             Rsin(θ)cos(ϕ)
             Rsin(ϕ)]

where

ϕ ∈ ℝ : angle between 0 and 2π
θ ∈ ℝ : angle between -π/2 and π/2
R ∈ ℝ : the radius of the sphere
*/
#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <iostream>
#include <set>

struct pmp_32ResultType {
    Eigen::Matrix<double, 3, 1> x_left_parenthesis_θ_comma_ϕ_right_parenthesis;
    pmp_32ResultType(const Eigen::Matrix<double, 3, 1> & x_left_parenthesis_θ_comma_ϕ_right_parenthesis)
    : x_left_parenthesis_θ_comma_ϕ_right_parenthesis(x_left_parenthesis_θ_comma_ϕ_right_parenthesis)
    {}
};

/**
 * pmp_32
 *
 * @param ϕ  angle between 0 and 2π
 * @param θ  angle between -π/2 and π/2
 * @param R  the radius of the sphere
 * @return x_left_parenthesis_θ_comma_ϕ_right_parenthesis
 */
pmp_32ResultType pmp_32(
    const double & ϕ,
    const double & θ,
    const double & R)
{
    Eigen::Matrix<double, 3, 1> x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0;
    x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0 << R * cos(θ) * cos(ϕ),
    R * sin(θ) * cos(ϕ),
    R * sin(ϕ);
    Eigen::Matrix<double, 3, 1> x_left_parenthesis_θ_comma_ϕ_right_parenthesis = x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0;

    return pmp_32ResultType(x_left_parenthesis_θ_comma_ϕ_right_parenthesis);
}


void generateRandomData(double & ϕ,
    double & θ,
    double & R)
{
    ϕ = rand() % 10;
    θ = rand() % 10;
    R = rand() % 10;
}


int main(int argc, char *argv[])
{
    srand((int)time(NULL));
    double ϕ;
    double θ;
    double R;
    generateRandomData(ϕ, θ, R);
    pmp_32ResultType func_value = pmp_32(ϕ, θ, R);
    std::cout<<"return value:\n"<<func_value.x_left_parenthesis_θ_comma_ϕ_right_parenthesis<<std::endl;
    return 0;
}

I❤️LA compiled to Python/NumPy/SciPy:

"""
from trigonometry: sin, cos
`x(θ, ϕ)` = [Rcos(θ)cos(ϕ)
             Rsin(θ)cos(ϕ)
             Rsin(ϕ)]

where

ϕ ∈ ℝ : angle between 0 and 2π
θ ∈ ℝ : angle between -π/2 and π/2
R ∈ ℝ : the radius of the sphere
"""
import numpy as np
import scipy
import scipy.linalg
from scipy import sparse
from scipy.integrate import quad
from scipy.optimize import minimize


class pmp_32ResultType:
    def __init__( self, x_left_parenthesis_θ_comma_ϕ_right_parenthesis):
        self.x_left_parenthesis_θ_comma_ϕ_right_parenthesis = x_left_parenthesis_θ_comma_ϕ_right_parenthesis


def pmp_32(ϕ, θ, R):
    """
    :param :ϕ : angle between 0 and 2π
    :param :θ : angle between -π/2 and π/2
    :param :R : the radius of the sphere
    """
    assert np.ndim(ϕ) == 0
    assert np.ndim(θ) == 0
    assert np.ndim(R) == 0

    x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0 = np.zeros((3, 1))
    x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0[0] = [R * np.cos(θ) * np.cos(ϕ)]
    x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0[1] = [R * np.sin(θ) * np.cos(ϕ)]
    x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0[2] = [R * np.sin(ϕ)]
    x_left_parenthesis_θ_comma_ϕ_right_parenthesis = x_left_parenthesis_θ_comma_ϕ_right_parenthesis_0
    return pmp_32ResultType(x_left_parenthesis_θ_comma_ϕ_right_parenthesis)


def generateRandomData():
    ϕ = np.random.randn()
    θ = np.random.randn()
    R = np.random.randn()
    return ϕ, θ, R


if __name__ == '__main__':
    ϕ, θ, R = generateRandomData()
    print("ϕ:", ϕ)
    print("θ:", θ)
    print("R:", R)
    func_value = pmp_32(ϕ, θ, R)
    print("return value: ", func_value.x_left_parenthesis_θ_comma_ϕ_right_parenthesis)

I❤️LA compiled to MATLAB:

function output = pmp_32(phi, theta, R)
% output = pmp_32(ϕ, θ, R)
%
%    from trigonometry: sin, cos
%    `x(θ, ϕ)` = [Rcos(θ)cos(ϕ)
%                 Rsin(θ)cos(ϕ)
%                 Rsin(ϕ)]
%    
%    where
%    
%    ϕ ∈ ℝ : angle between 0 and 2π
%    θ ∈ ℝ : angle between -π/2 and π/2
%    R ∈ ℝ : the radius of the sphere
    if nargin==0
        warning('generating random input data');
        [phi, theta, R] = generateRandomData();
    end
    function [phi, theta, R] = generateRandomData()
        phi = randn();
        theta = randn();
        R = randn();
    end

    assert(numel(phi) == 1);
    assert(numel(theta) == 1);
    assert(numel(R) == 1);

    x_theta_phi_0 = zeros(3, 1);
    x_theta_phi_0(1,:) = [R * cos(theta) * cos(phi)];
    x_theta_phi_0(2,:) = [R * sin(theta) * cos(phi)];
    x_theta_phi_0(3,:) = [R * sin(phi)];
    x_theta_phi = x_theta_phi_0;
    output.x_theta_phi = x_theta_phi;
end

I❤️LA compiled to LaTeX:

\documentclass[12pt]{article}
\usepackage{mathdots}
\usepackage[bb=boondox]{mathalfa}
\usepackage{mathtools}
\usepackage{amssymb}
\usepackage{libertine}
\DeclareMathOperator*{\argmax}{arg\,max}
\DeclareMathOperator*{\argmin}{arg\,min}
\usepackage[paperheight=8in,paperwidth=4in,margin=.3in,heightrounded]{geometry}
\let\originalleft\left
\let\originalright\right
\renewcommand{\left}{\mathopen{}\mathclose\bgroup\originalleft}
\renewcommand{\right}{\aftergroup\egroup\originalright}
\begin{document}

\begin{center}
\resizebox{\textwidth}{!} 
{
\begin{minipage}[c]{\textwidth}
\begin{align*}
\text{from trigonometry import sin, cos}\\
\textit{x(θ, ϕ)} & = \begin{bmatrix}
\mathit{R}cos\left( \mathit{θ} \right)cos\left( \mathit{ϕ} \right)\\
\mathit{R}sin\left( \mathit{θ} \right)cos\left( \mathit{ϕ} \right)\\
\mathit{R}sin\left( \mathit{ϕ} \right)\\
\end{bmatrix} \\
\intertext{where} 
\mathit{ϕ} & \in \mathbb{R} \text{ angle between 0 and 2π} \\
\mathit{θ} & \in \mathbb{R} \text{ angle between -π/2 and π/2} \\
\mathit{R} & \in \mathbb{R} \text{ the radius of the sphere} \\
\\
\end{align*}
\end{minipage}
}
\end{center}

\end{document}

I❤️LA LaTeX output: