!> \~japanese
!! \brief 幾何学的な計算を行う手続きを提供するモジュール
!! \~english
!! \brief This module provides some subroutines to perform the calculations associated with geometry.
!! \~
!!
!! <br><br>
!! \b Copyright (C) GFD Dennou Club, 2011-2012. All rights reserved. <br>
!! \b license ?? <br>
!! \author Yuta Kawai
!!
module igmcore_geometry

  ! モジュール引用 ; Use statements
  !
  
  ! 種類型パラメタ
  ! Kind type parameter
  !
  use dc_types, only: DP         ! 倍精度実数型. Double precision. 


  ! 線形代数
  ! Linear algebra
  !
  use igmcore_linear_algebra, only: &
    & vec_length, cross

  ! 宣言文 ;  Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedure
  !
  public :: triangle_area, tri_grav_center, polygon_grav_center

contains

!
!> \~japanese
!! \brief 三角形(各頂点を P1, P2, P3 とする)の面積を求める.
!!
!! @param[in] p1  三角形の頂点 P1 の位置ベクトル.
!! @param[in] p2  三角形の頂点 P2 の位置ベクトル.
!! @param[in] p3  三角形の頂点 P3 の位置ベクトル.
!! @return        三角形の面積.
!!
!! \~english
!! \brief 三角形(各頂点を P1, P2, P3 とする)の面積を求める.
!! 
!! @param[in] p1  三角形の頂点 P1 の位置ベクトル. 
!! @param[in] p2  三角形の頂点 P2 の位置ベクトル. 
!! @param[in] p3  三角形の頂点 P3 の位置ベクトル. 
!! @return        三角形の面積. 
!!
function triangle_area( &
  & p1, p2, p3          &  ! (in)
  & ) result(area)
  
  ! 宣言文 ; Declaration statements
  !
  real(DP), intent(in) :: p1(3)  ! 三角形の頂点 P1 の位置ベクトル
  real(DP), intent(in) :: p2(3)  ! 三角形の頂点 P2 の位置ベクトル
  real(DP), intent(in) :: p3(3)  ! 三角形の頂点 P3 の位置ベクトル
  real(DP) area                  ! 三角形の面積

  ! 実行文 ; Executable statements
  ! 

  area = 0.5d0 * vec_length(cross(p1-p2, p3-p2))

end function

!
!> \~japanese
!! \brief 三角形(各頂点を P1, P2, P3 とする)の重心の座標を求める.
!!
!! @param[in] p1  三角形の頂点 P1 の位置ベクトル.
!! @param[in] p2  三角形の頂点 P2 の位置ベクトル.
!! @param[in] p3  三角形の頂点 P3 の位置ベクトル.
!! @return        三角形の重心の位置ベクトル.
!!
!! \~english
!! \brief 三角形(各頂点を P1, P2, P3 とする)の重心の座標を求める.
!!
!! @param[in] p1  三角形の頂点 P1 の位置ベクトル. 
!! @param[in] p2  三角形の頂点 P2 の位置ベクトル. 
!! @param[in] p3  三角形の頂点 P3 の位置ベクトル. 
!! @return        三角形の重心の位置ベクトル. 
!!
function tri_grav_center( &
  & p1, p2, p3            &  ! (in)
  & ) result(p)

  ! 宣言文 ; Declaration statements
  !
  real(DP), intent(in) :: p1(3)  ! 三角形の頂点 P1 の位置ベクトル
  real(DP), intent(in) :: p2(3)  ! 三角形の頂点 P2 の位置ベクトル
  real(DP), intent(in) :: p3(3)  ! 三角形の頂点 P3 の位置ベクトル
  real(DP) :: p(3)               ! 三角形の重心の位置ベクトル

  ! 実行文 ; Executable statements
  !

  p = ( p1 + p2 + p3 ) /3.0d0

end function tri_grav_center

!
!> \~japanese
!! \brief 多角形の重心を求める.
!!
!! @param[in] pt_siz  多角形の頂点数.
!! @param[in] points  多角形の各頂点の位置ベクトルを頂点数だけ格納した配列.
!! @return            多角形の重心の位置ベクトル.
!!
!! \~english
!! \brief 多角形の重心を求める.
!!
!! @param[in] pt_siz  多角形の頂点数. 
!! @param[in] points  多角形の各頂点の位置ベクトルを頂点数だけ格納した配列. 
!! @return            多角形の重心の位置ベクトル. 
!!
function polygon_grav_center( &
  & pt_size, points           &  ! (in)           
  & ) result(grav_p)

  ! 宣言文 ; Declaration statements
  !
  integer, intent(in) :: pt_size               ! 多角形の頂点数
  real(DP), intent(in) :: points(pt_size, 3)   ! 多角形の各頂点の位置ベクトルを頂点数だけ格納した配列
  real(DP) grav_p(3)                           ! 多角形の重心の位置ベクトル

  ! 作業変数 
  ! Work variables
  !
  integer i
  
  ! 実行文 ; Executable statements
  !

  grav_p = 0.0d0
  do i=1, pt_size
    grav_p = grav_p + points(i, :)
  end do

  grav_p = grav_p / pt_size

end function polygon_grav_center

end module igmcore_geometry
