Im letzten Post wollte ich deutlich machen, welche Art von Fehler passieren, wenn zwischen den TypenPoint3D und Vector3D keinen semantischen Unterschied gemacht wird. Also, wenn ein Rechenergebnis von der Bedeutung ein Vektor ist, es aber in einem Punkt Datentyp gespeichert wird.
Die erste Lösung war, einen zusätzlichen Datentyp Vector3D zu erstellen, welcher sich genau wie ein Point3D verhält, aber von der Bedeutung eine andere hat. Dies lässt sich auch noch ohne concepts realisieren. Dazu das selbe Beispiel von Part1 diesmal in FORTRAN. Und im nächsten Teil gibts dann das erste concept.
Da ich nicht weiß ob es in FORTRAN möglich ist, von einem Array zu erben, noch ob man operator()() überladen kann, hier eine Version mit etwas mehr Tipparbeit.
Wichtig ist aber erstmal nur, dass die selbe Art von Fehlermeldung erzeugt werden kann.
conceptpart2.F90
normal = normalenVector(tri)
1
Error: Can't convert TYPE(vector3d_t) to TYPE(point3d_t) at (1)
module test_m
 implicit none
 
  type Point3D_t
    real(8) :: xyz(3)
  end type
  type Vector3D_t
    real(8) :: xyz(3) 
  end type
  type Triangle_t
      type(Point3D_t) :: points(3)
  end type
  interface operator(-)
    module procedure minus1
  end interface
  
  contains
  function minus1(p1, p2) result(p3)
    implicit none
    type(Point3D_t), intent(in) :: p1, p2
    type(Point3D_t) :: p3
    p3 = Point3D_t( (/ p1%xyz(1)-p2%xyz(1), p1%xyz(2)-p2%xyz(2), p1%xyz(3)-p2%xyz(3) /) )
  end function
  function normalenVector(tri) result(normal)
    implicit none
    type(Triangle_t), intent(in) :: tri
    type(Point3D_t) :: vec1, vec2
    type(Vector3D_t) :: normal
    
      vec1 = tri%points(2)-tri%points(1)
      vec2 = tri%points(3)-tri%points(1)
      normal = Vector3D_t( (/ vec1%xyz(2)*vec2%xyz(3)-vec1%xyz(3)*vec2%xyz(2), &
&                  vec1%xyz(3)*vec2%xyz(1)-vec1%xyz(1)*vec2%xyz(3), &
&                  vec1%xyz(1)*vec2%xyz(2)-vec1%xyz(2)*vec2%xyz(1) /) )
  end function
 
end module
program main
  use test_m
  implicit none
  type(Triangle_t) :: tri
  type(Point3D_t) :: normal
    
  tri = Triangle_t((/ Point3D_t((/0, 0, 0/)), Point3D_t((/10, 0, 0/)), Point3D_t((/10, 10, 0/)) /))
  normal = normalenVector(tri)
end program