PROGRAM Points_and_Lines
!----------------------------------------------------------------------
! Program to read two points P1 and P2 represented as structures,
! calculate the distance between P1 and P2, and find the slope-
! intercept equation of the line determined by P1 and P2. Identifiers
! used are:
!    Point    : derived type representing points in two dimensions
!    P1, P2   : two points being processed
!    Distance : function to calculate distance between points
!    FindLine : subroutine to find the equation of a line
!    Response : user response
!
! Input:   Coordinates of points.
! Output:  User prompts, labels, distance between two points, and
!          slope-intercept of equation of line through the points.
!----------------------------------------------------------------------

  IMPLICIT NONE
  TYPE Point
    REAL :: X, Y
  END TYPE Point

  TYPE(Point) :: P1, P2
  CHARACTER(1) :: Response

  DO
     WRITE (*, '(1X, A)', ADVANCE = "NO") &
           "Enter coordinates of points P1 and P2: "
     READ *, P1%X, P1%Y, P2%X, P2%Y
     PRINT '(1X, 2(A, "(", F5.2, ",", F5.2, ")"), " is ", F5.2)', &
           "Distance between ", P1%X, P1%Y, " and ", P2%X, P2%Y, &
           Distance(P1, P2)
     CALL FindLine(P1, P2)
     WRITE (*, '(/ 1X, A)', ADVANCE = "NO") "More points (Y or N)? "
     READ *, Response
     IF (Response /= "Y") EXIT
  END DO

CONTAINS

  !--Distance-----------------------------------------------------------
  ! Function to calculate the distance between points P1 and P2
  !
  ! Accepts:   Structures P1 and P2 of type Point
  ! Returns:   Distance between P1 and P2
  !---------------------------------------------------------------------

  FUNCTION Distance(P1, P2)

    TYPE(Point), INTENT(IN) :: P1, P2
    REAL :: Distance

    Distance = SQRT((P2%x - P1%x)**2 + (P2%y - P1%y)**2)

  END FUNCTION Distance


  !--FindLine-----------------------------------------------------------
  ! Subroutine to find the slope-intercept equation  y = mx + b of
  ! the line passing though points P1 and P2.  Local variables used:
  !   M : slope of line
  !   B : y intercept of line
  !
  ! Accepts: Structures P1 and P2 of type Point
  ! Output:  Equation of line determined by P1 and P2
  !---------------------------------------------------------------------

  SUBROUTINE FindLine(P1, P2)

    TYPE(Point), INTENT(IN) :: P1, P2
    REAL :: M,  B

    IF (P1%X == P2%X) THEN
       PRINT '(1X, A, F5.2)', "Line is vertical line  x = ", P1%X
    ELSE
       M = (P2%Y - P1%Y) / (P2%X - P1%X)
       B = P1%Y - M * P1%X
       PRINT '(1X, 2(A, F5.2))', "Equation of line is y = ", &
                                 M, "x + ", B
    END IF
  END SUBROUTINE FindLine

END PROGRAM Points_and_Lines
