add_cylinder Subroutine

private subroutine add_cylinder(me, v1, v2, radius, num_points, initial_cap, final_cap, initial_normal, final_normal, final_normal_used, initial_vector, final_initial_vector_used)

Add a cylinder to an STL file.

The cylinder is specified by the initial and final x,y,z coordinates. Optionally, an initial and final normal vector can be specified (if not specified, then a default one is constructed).

Type Bound

stl_file

Arguments

Type IntentOptional Attributes Name
class(stl_file), intent(inout) :: me
real(kind=wp), intent(in), dimension(3) :: v1

coordinates of initial point

real(kind=wp), intent(in), dimension(3) :: v2

coordinates of final point

real(kind=wp), intent(in) :: radius

radius of the cylinder

integer, intent(in) :: num_points

number of point on the circle (>=3)

logical, intent(in) :: initial_cap

add a cap plate to the initial point

logical, intent(in) :: final_cap

add a cap plate to the final point

real(kind=wp), intent(in), optional, dimension(3) :: initial_normal

outward normal vector for initial circle

real(kind=wp), intent(in), optional, dimension(3) :: final_normal

outward normal vector for final circle

real(kind=wp), intent(out), optional, dimension(3) :: final_normal_used

outward normal vector for final circle actually used

real(kind=wp), intent(in), optional, dimension(3) :: initial_vector

vector to use to generate the initial circle (x_unit by default)

real(kind=wp), intent(out), optional, dimension(3) :: final_initial_vector_used

the initial vector used for the final cap to generate the points


Calls

proc~~add_cylinder~~CallsGraph proc~add_cylinder stl_file%add_cylinder proc~add_plate stl_file%add_plate proc~add_cylinder->proc~add_plate proc~generate_circle stl_file%generate_circle proc~add_cylinder->proc~generate_circle proc~unit unit proc~add_cylinder->proc~unit proc~generate_circle->proc~add_plate proc~generate_circle->proc~unit proc~axis_angle_rotation axis_angle_rotation proc~generate_circle->proc~axis_angle_rotation proc~perpendicular perpendicular proc~generate_circle->proc~perpendicular proc~vector_projection_on_plane vector_projection_on_plane proc~generate_circle->proc~vector_projection_on_plane proc~axis_angle_rotation->proc~unit proc~cross cross proc~axis_angle_rotation->proc~cross proc~perpendicular->proc~unit proc~vector_projection vector_projection proc~vector_projection_on_plane->proc~vector_projection

Called by

proc~~add_cylinder~~CalledByGraph proc~add_cylinder stl_file%add_cylinder proc~add_arrow stl_file%add_arrow proc~add_arrow->proc~add_cylinder proc~add_curve stl_file%add_curve proc~add_curve->proc~add_cylinder proc~add_axes stl_file%add_axes proc~add_axes->proc~add_arrow

Source Code

    subroutine add_cylinder(me,v1,v2,radius,num_points,initial_cap,final_cap,&
                            initial_normal,final_normal,final_normal_used,initial_vector,final_initial_vector_used)

    implicit none

    class(stl_file),intent(inout)              :: me
    real(wp),dimension(3),intent(in)           :: v1                        !! coordinates of initial point
    real(wp),dimension(3),intent(in)           :: v2                        !! coordinates of final point
    real(wp),intent(in)                        :: radius                    !! radius of the cylinder
    integer,intent(in)                         :: num_points                !! number of point on the circle (>=3)
    logical,intent(in)                         :: initial_cap               !! add a cap plate to the initial point
    logical,intent(in)                         :: final_cap                 !! add a cap plate to the final point
    real(wp),dimension(3),intent(in),optional  :: initial_normal            !! outward normal vector for initial circle
    real(wp),dimension(3),intent(in),optional  :: final_normal              !! outward normal vector for final circle
    real(wp),dimension(3),intent(out),optional :: final_normal_used         !! outward normal vector for final circle
                                                                            !! actually used
    real(wp),dimension(3),intent(in),optional  :: initial_vector            !! vector to use to generate the initial
                                                                            !! circle (x_unit by default)
    real(wp),dimension(3),intent(out),optional :: final_initial_vector_used !! the initial vector used for the final
                                                                            !! cap to generate the points

    integer :: i  !! counter
    integer :: nc !! number of points on the circle
    real(wp),dimension(3) :: n0 !! normal vector for initial circle
    real(wp),dimension(3) :: nf !! normal vector for final circle
    real(wp),dimension(:,:),allocatable :: n0_cap_points !! points for the initial cap
    real(wp),dimension(:,:),allocatable :: nf_cap_points !! points for the final cap

    nc = max(3, num_points)

    ! compute the end unit vectors
    !
    !        1 _________2
    !        |          |
    !  n0 <--*----------*--> nf
    !        |          |
    !         ----------

    if (present(initial_normal)) then
        n0 = unit(initial_normal)
    else
        n0 = unit(v1-v2)
    end if
    if (present(final_normal)) then
        nf = unit(final_normal)
    else
        nf = unit(v2-v1)
    end if
    if (present(final_normal_used)) final_normal_used = nf ! return if necessary

    ! create the points on the initial cap (optionally add the plate)
    call me%generate_circle(v1,radius,n0,nc,initial_cap,n0_cap_points,initial_vector=initial_vector)

    ! create the points on the final cap (optionally add the plate)
    ! [use the same initial vector to sure that the plate will form a good cylinder]
    call me%generate_circle(v2,radius,nf,nc,final_cap,nf_cap_points,&
                            initial_vector=unit(n0_cap_points(:,1)-v1),cw=.true.)
    if (present(final_initial_vector_used)) final_initial_vector_used = unit(nf_cap_points(:,1)-v2)

    ! now connect the points to form the cylinder:
    !   1----2  nf
    !   |  / |
    !   | /  |
    !   1----2  n0
    do i = 1, nc-1
        call me%add_plate(n0_cap_points(:,i),n0_cap_points(:,i+1),nf_cap_points(:,i+1))
        call me%add_plate(n0_cap_points(:,i),nf_cap_points(:,i+1),nf_cap_points(:,i))
    end do
    ! last one:
    !   n----1  nf
    !   |  / |
    !   | /  |
    !   n----1  n0
   call me%add_plate(n0_cap_points(:,nc),n0_cap_points(:,1),nf_cap_points(:,1))
   call me%add_plate(n0_cap_points(:,nc),nf_cap_points(:,1),nf_cap_points(:,nc))

    end subroutine add_cylinder