#!/usr/bin/env python
# -*- coding: utf-8 -*-

##
# @file blending_mechanics_visualization.py
# @brief Visualizes spatial alpha blending mechanics with and without gamma correction.
#
# @details
# This program generates a detailed visualization of projector edge blending
# in an overlap region. It compares:
# - Linear alpha blending (baseline / incorrect approach)
# - Gamma-corrected alpha blending (final solution)
#
# The graph highlights how gamma correction compensates for nonlinear
# projector luminance response, preventing visible dark seams
# in the overlap region.
#
# The output image is designed for inclusion in technical documentation
# or a project wiki to explain blending mechanics visually.

import numpy as np
import matplotlib.pyplot as plt


##
# @brief Plots spatial alpha blending behavior in an overlap region.
#
# @details
# This function simulates the intensity distribution of two overlapping
# projectors across a horizontal overlap zone.
#
# Two blending strategies are visualized:
# 1. Linear alpha blending (y = x)
# 2. Gamma-corrected alpha blending (y = x^(1/gamma))
#
# The resulting plot illustrates how gamma correction increases effective
# light energy in the overlap region, correcting the dark band artifact
# caused by naive linear blending.
#
# The shaded regions emphasize the difference in projected light energy
# between linear and gamma-corrected approaches.
#
# @note
# This visualization is analytical and explanatory in nature.
# It does not represent raw pixel blending, but projected luminance behavior.
#
# @return None
def plot_blending_mechanics_unique():
    ##
    # @brief Define overlap region configuration.
    #
    # @details
    # overlap_pixels represents the horizontal width (in pixels)
    # where two projectors overlap.
    overlap_pixels = 256  # Example: Change this to your actual overlap width

    ##
    # @brief Generate pixel coordinate ranges.
    #
    # @details
    # x_pixels is used for spatial positioning,
    # while x_normalized maps the same region into [0, 1]
    # for alpha calculations.
    x_pixels = np.linspace(0, overlap_pixels, 500)
    x_normalized = np.linspace(0, 1, 500)

    ##
    # @brief Compute linear alpha blending weights (baseline).
    #
    # @details
    # These represent a naive linear fade-out / fade-in
    # without accounting for projector gamma characteristics.
    alpha_left_lin = 1.0 - x_normalized
    alpha_right_lin = x_normalized

    ##
    # @brief Compute gamma-corrected alpha blending weights.
    #
    # @details
    # Gamma correction compensates for nonlinear luminance response
    # of projectors.
    #
    # Formula:
    # @f[
    #   \alpha_{corrected} = \alpha^{(1/\gamma)}
    # @f]
    gamma = 2.2  # Projector gamma value
    alpha_left_corr = np.power(alpha_left_lin, 1.0 / gamma)
    alpha_right_corr = np.power(alpha_right_lin, 1.0 / gamma)

    ##
    # @brief Initialize plotting canvas.
    plt.figure(figsize=(10, 6))

    ##
    # @brief Plot gamma-corrected projector outputs.
    #
    # @details
    # These curves represent the final projected light intensities
    # after gamma compensation.
    plt.plot(x_pixels, alpha_left_corr, 'b-', linewidth=3, label='Left Projector Output')
    plt.plot(x_pixels, alpha_right_corr, 'r-', linewidth=3, label='Right Projector Output')

    ##
    # @brief Plot linear blending reference curves.
    #
    # @details
    # Dashed lines illustrate the baseline case where no gamma
    # correction is applied.
    plt.plot(x_pixels, alpha_left_lin, 'k:', linewidth=1.5, alpha=0.5,
             label='Linear Reference (No Correction)')
    plt.plot(x_pixels, alpha_right_lin, 'k:', linewidth=1.5, alpha=0.5)

    ##
    # @brief Visualize additional light energy introduced by gamma correction.
    #
    # @details
    # The shaded regions represent the difference between
    # linear and gamma-corrected intensity distributions,
    # emphasizing how gamma correction boosts luminance
    # in the overlap region.
    plt.fill_between(x_pixels, alpha_left_corr, alpha_left_lin,
                     color='blue', alpha=0.1)
    plt.fill_between(x_pixels, alpha_right_corr, alpha_right_lin,
                     color='red', alpha=0.1)

    ##
    # @brief Annotate gamma compensation effect.
    #
    # @details
    # Highlights the central region where gamma correction
    # mitigates the dark band artifact.
    plt.text(overlap_pixels / 2, 0.8,
             'Gamma Boost Region\n(Corrects Dark Band)',
             horizontalalignment='center',
             fontsize=10,
             bbox=dict(facecolor='white', alpha=0.8, edgecolor='none'))

    ##
    # @brief Configure graph labels and appearance.
    plt.title(f'Spatial Intensity Distribution (Overlap: {overlap_pixels}px)',
              fontsize=14, fontweight='bold')
    plt.xlabel('Pixel Position in Overlap Zone', fontsize=12)
    plt.ylabel('Projected Light Intensity (0.0 - 1.0)', fontsize=12)
    plt.legend()
    plt.grid(True, alpha=0.3)

    ##
    # @brief Save visualization to file.
    #
    # @details
    # The generated image is saved as a PNG file for
    # easy embedding into documentation or wiki pages.
    plt.savefig('custom_blending_curve.png', dpi=100)
    print("Saved: custom_blending_curve.png")


##
# @brief Program entry point.
#
# @details
# Executes the blending mechanics visualization when the script
# is run directly.
if __name__ == "__main__":
    plot_blending_mechanics_unique()