Generate the points in a circle, and optionally add it as a plate.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(stl_file), | intent(inout) | :: | me | |||
real(kind=wp), | intent(in), | dimension(3) | :: | c |
center of the circle |
|
real(kind=wp), | intent(in) | :: | radius |
radius of the cylinder |
||
real(kind=wp), | intent(in), | dimension(3) | :: | n |
normal vector to the circle |
|
integer, | intent(in) | :: | nc |
number of points on the circle (must be at least 3) |
||
logical, | intent(in) | :: | add_circle |
to also add to the circle as a plate |
||
real(kind=wp), | intent(out), | dimension(:,:), allocatable | :: | circle |
points on the circle |
|
real(kind=wp), | intent(in), | optional, | dimension(3) | :: | initial_vector |
vector to use to generate the initial circle (x_unit by default) |
logical, | intent(in), | optional | :: | cw |
generate the points in the clockwise direction abound n (default is false) |
subroutine generate_circle(me,c,radius,n,nc,add_circle,circle,initial_vector,cw) implicit none class(stl_file),intent(inout) :: me real(wp),dimension(3),intent(in) :: c !! center of the circle real(wp),intent(in) :: radius !! radius of the cylinder real(wp),dimension(3),intent(in) :: n !! normal vector to the circle integer,intent(in) :: nc !! number of points on the circle !! (must be at least 3) logical,intent(in) :: add_circle !! to also add to the circle as a plate real(wp),dimension(:,:),allocatable,intent(out) :: circle !! points on the circle real(wp),dimension(3),intent(in),optional :: initial_vector !! vector to use to generate the initial !! circle (x_unit by default) logical,intent(in),optional :: cw !! generate the points in the clockwise !! direction abound n (default is false) real(wp),dimension(3) :: v !! initial vector for the circle integer :: i !! counter real(wp) :: factor !! cw/ccw factor logical :: compute_initial_vector !! if we need to compute an initial vector if (nc<3) error stop 'number of points on a circle must be at least 3' allocate(circle(3,nc)) ! circle = -999 factor = one if (present(cw)) then if (cw) factor = -one end if if (present(initial_vector)) then compute_initial_vector = all(initial_vector==zero) else compute_initial_vector = .true. end if ! start with an initial vector on the circle (perpendicular to n0) ! [project x to circle (or y if x is parallel to n)] if (.not. compute_initial_vector) then v = unit(vector_projection_on_plane(initial_vector,n)) if (.not. perpendicular(v, n) .or. all(v==zero)) then ! fall back to x or y axis v = unit(vector_projection_on_plane(x_unit,n)) if (.not. perpendicular(v, n) .or. all(v==zero)) then v = unit(vector_projection_on_plane(y_unit,n)) end if end if else v = unit(vector_projection_on_plane(x_unit,n)) if (.not. perpendicular(v, n) .or. all(v==zero)) then v = unit(vector_projection_on_plane(y_unit,n)) end if end if v = radius * unit(v) ! generate the points by rotating the initial vector around the circle: circle(:,1) = c + v do i = 2, nc circle(:,i) = c + axis_angle_rotation(v,n,(i-1)*factor*(360.0_wp/nc)) if (add_circle) then ! draw the initial cap call me%add_plate(c,circle(:,i),circle(:,i-1)) end if end do ! final plate that connects last to first if (add_circle) call me%add_plate(c,circle(:,1),circle(:,nc)) end subroutine generate_circle