add_curve Subroutine

private subroutine add_curve(me, x, y, z, radius, num_points, initial_cap, initial_normal, final_cap, final_normal, initial_vector)

Add a curve to an STL file.

A curve is a joined set of cylinders with no internal caps.

Type Bound

stl_file

Arguments

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

x coordinate array

real(kind=wp), intent(in), dimension(:) :: y

y coordinate array

real(kind=wp), intent(in), dimension(:) :: z

z coordinate array

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

radius of the cylinder

integer, intent(in) :: num_points

number of point on the cylinder perimeter

logical, intent(in), optional :: initial_cap

add a cap plate to the initial point

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

outward normal vector for initial circle

logical, intent(in), optional :: final_cap

add a cap plate to the final point

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

outward normal vector for final circle

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

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


Calls

proc~~add_curve~~CallsGraph proc~add_curve stl_file%add_curve proc~add_cylinder stl_file%add_cylinder proc~add_curve->proc~add_cylinder proc~unit unit proc~add_curve->proc~unit proc~add_cylinder->proc~unit 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~generate_circle->proc~unit proc~generate_circle->proc~add_plate 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

Source Code

    subroutine add_curve(me,x,y,z,radius,num_points,&
                         initial_cap,initial_normal,final_cap,final_normal,initial_vector)

    implicit none

    class(stl_file),intent(inout)             :: me
    real(wp),dimension(:),intent(in)          :: x              !! x coordinate array
    real(wp),dimension(:),intent(in)          :: y              !! y coordinate array
    real(wp),dimension(:),intent(in)          :: z              !! z coordinate array
    real(wp),intent(in)                       :: radius         !! radius of the cylinder
    integer,intent(in)                        :: num_points     !! number of point on the cylinder perimeter
    logical,intent(in),optional               :: initial_cap    !! add a cap plate to the initial point
    real(wp),dimension(3),intent(in),optional :: initial_normal !! outward normal vector for initial circle
    logical,intent(in),optional               :: final_cap      !! add a cap plate to the final point
    real(wp),dimension(3),intent(in),optional :: final_normal   !! outward normal vector for final circle
    real(wp),dimension(3),intent(in),optional :: initial_vector !! vector to use to generate the first circle (x_unit by default)

    integer               :: i      !! counter
    integer               :: n      !! number of points
    real(wp),dimension(3) :: nv     !! for intermediate normal vectors
    real(wp),dimension(3) :: nv_tmp !! for intermediate normal vectors
    real(wp),dimension(3) :: v      !! for intermediate initial vectors

    n = min(size(x), size(y), size(z))
    if (n<2) error stop 'error: a curve must have more than one point'

    ! first cylinder [no final cap unless only two points]
    call me%add_cylinder([x(1),y(1),z(1)],&
                         [x(2),y(2),z(2)],&
                         radius,num_points,&
                         initial_cap=initial_cap,initial_normal=initial_normal,initial_vector=initial_vector,&
                         final_cap=n==2,final_normal_used=nv,final_initial_vector_used=v)

    if (n>3) then
        ! intermediate cylinders (the initial normal is the final normal from the previous cylinder)
        do i = 2, n-2
            call me%add_cylinder([x(i),y(i),z(i)],&
                                 [x(i+1),y(i+1),z(i+1)],&
                                 radius,num_points,&
                                 initial_cap=.false.,initial_normal=-nv,&
                                 final_cap=.false.,final_normal_used=nv_tmp,&
                                 initial_vector=v)
            nv = unit(nv_tmp)
        end do
    end if

    ! last cylinder [no initial cap]
    if (n>=3) then
        call me%add_cylinder([x(n-1),y(n-1),z(n-1)],&
                             [x(n),y(n),z(n)],&
                             radius,num_points,&
                             final_cap=final_cap,final_normal=final_normal,&
                             initial_normal=-nv,initial_cap=.false.,&
                             initial_vector=v)
    end if

    end subroutine add_curve