AOI_PROJECTION

This function computes the cosine of the angle of incidence.

It returns the projection of the sun’s unit vector onto the surface’s normal unit vector. Negative values indicate the sun is behind the surface.

Excel Usage

=AOI_PROJECTION(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth)
  • surface_tilt (list[list], required): Panel tilt from horizontal (degrees).
  • surface_azimuth (list[list], required): Panel azimuth direction (degrees).
  • solar_zenith (list[list], required): Solar zenith angle (degrees).
  • solar_azimuth (list[list], required): Solar azimuth angle (degrees).

Returns (list[list]): 2D list of AOI projections (unitless), or an error string.

Example 1: Projection for sun directly normal to surface

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
30 180 30 180

Excel formula:

=AOI_PROJECTION({30}, {180}, {30}, {180})

Expected output:

1

Example 2: Projection negative when sun is behind surface

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
30 180 30 0

Excel formula:

=AOI_PROJECTION({30}, {180}, {30}, {0})

Expected output:

0.5

Example 3: Vectorized projection over two sun positions

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
20 20 180 180 20 60 180 210

Excel formula:

=AOI_PROJECTION({20,20}, {180,180}, {20,60}, {180,210})

Expected output:

Result
1
0.726361
Example 4: Scalar projection inputs

Inputs:

surface_tilt surface_azimuth solar_zenith solar_azimuth
20 180 20 180

Excel formula:

=AOI_PROJECTION(20, 180, 20, 180)

Expected output:

1

Python Code

Show Code
import pandas as pd
import numpy as np
from pvlib.irradiance import aoi_projection as result_func

def aoi_projection(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth):
    """
    Calculate the dot product of the sun position and surface normal (cosine of AOI).

    See: https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.aoi_projection.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        surface_tilt (list[list]): Panel tilt from horizontal (degrees).
        surface_azimuth (list[list]): Panel azimuth direction (degrees).
        solar_zenith (list[list]): Solar zenith angle (degrees).
        solar_azimuth (list[list]): Solar azimuth angle (degrees).

    Returns:
        list[list]: 2D list of AOI projections (unitless), or an error string.
    """
    try:
        def flatten_num(data):
            if not isinstance(data, list): return [float(data)]
            flat = []
            for row in data:
                row = row if isinstance(row, list) else [row]
                for val in row:
                    if val == "": flat.append(float('nan'))
                    else: flat.append(float(val))
            return flat

        t_list = flatten_num(surface_tilt)
        a_list = flatten_num(surface_azimuth)
        z_list = flatten_num(solar_zenith)
        az_list = flatten_num(solar_azimuth)

        n = len(t_list)
        if n == 0 or len(a_list) != n or len(z_list) != n or len(az_list) != n:
            return "Error: All input arrays must have the same non-zero length"

        res = result_func(
            surface_tilt=np.array(t_list),
            surface_azimuth=np.array(a_list),
            solar_zenith=np.array(z_list),
            solar_azimuth=np.array(az_list)
        )

        return [[float(v) if not pd.isna(v) else ""] for v in res]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Panel tilt from horizontal (degrees).
Panel azimuth direction (degrees).
Solar zenith angle (degrees).
Solar azimuth angle (degrees).