Unverified Commit f613e72a authored by djabaay's avatar djabaay Committed by GitHub
Browse files

Adding overloaded assignments for geometries, and 90 degree rotation. (#309)

* Adding overloaded assignments for geometries, and 90 degree rotation.

Description:
These functions are needed to help speed up the geometry processing in
MPACT.

VERA-dev Issue # - ####

* Removing overloaded assignment.

Description:
Should be unnecessary for types with only intrinsics and no pointers.

VERA-dev Issue # - ####

* Addressing Pull Request comments.

Description:
Adding subroutine headers and explanations.

VERA-dev Issue # - ####
parent 0d333ffd
......@@ -21,6 +21,7 @@ PUBLIC :: Rational_Fraction
PUBLIC :: GreatestCommonDivisor
PUBLIC :: LeastCommonMultiple
PUBLIC :: ATAN2PI
PUBLIC :: RotateQtrClockwise
INTERFACE LeastCommonMultiple
MODULE PROCEDURE LeastCommonMultiple_scalar
......@@ -243,4 +244,39 @@ ELEMENTAL FUNCTION ATAN2PI(x,y) RESULT(theta)
IF(.NOT.(theta .APPROXGE. 0.0_SRK)) theta=TWOPI+theta
ENDFUNCTION ATAN2PI
!
!-------------------------------------------------------------------------------
!> @brief This routine will rotate the input x and y coordinates @nrot number of
!> clockwise quarter rotations.
!> @param x the x-coordinate
!> @param y the y-coordinate
!> @param nrot the number of clockwise quarter rotations
!>
!> @note: Values from [-3,-1] will be handled as well, even though they
!> represent counter clockwise rotations. If nrot == 0, no rotations are
!> performed. The results of these three rotations were taken from the
!> rotation matrix:
!> [cos(theta) -sin(theta) * [x
!> sin(theta) cos(theta)] y] where theta is degrees, CW.
!>
ELEMENTAL SUBROUTINE RotateQtrClockwise(x,y,nrot)
REAL(SRK),INTENT(INOUT) :: x
REAL(SRK),INTENT(INOUT) :: y
INTEGER(SIK),INTENT(IN) :: nrot
REAL(SRK) :: tmp
SELECTCASE(MOD(nrot,4))
CASE(1,-3) !90 CW/270 CCW
tmp=y
y=-x
x=tmp
CASE(2,-2) !180 CW/180 CCW
x=-x
y=-y
CASE(3,-1) !270 CW/90 CCW
tmp=x
x=-y
y=tmp
ENDSELECT
ENDSUBROUTINE RotateQtrClockwise
!
ENDMODULE ExtendedMath
......@@ -494,8 +494,8 @@ ENDFUNCTION inside_OBBoxType
!
!-------------------------------------------------------------------------------
!> @brief Defines the 'is equal to' operation between two OBBoxes e.g. @c b0==b1
!> @param p0 the first box
!> @param p1 the second box
!> @param b0 the first box
!> @param b1 the second box
!> @returns @c bool the boolean result of the operation
!>
!> Function is elemental so it can be used on an array of boxes.
......
......@@ -16,6 +16,7 @@
MODULE Geom_Points
USE IntrType
USE Constants_Conversion
USE ExtendedMath
IMPLICIT NONE
PRIVATE !Default contents of module to private
......@@ -53,6 +54,9 @@ TYPE :: PointType
!> @copybrief GeomPoints::clear_PointType
!> @copydetails GeomPoints::clear_PointType
PROCEDURE,PASS :: clear => clear_PointType
!> @copybrief GeomPoints::RotateQtrClockwise_PointType
!> @copydetails GeomPoints::RotateQtrClockwise_PointType
PROCEDURE,PASS :: RotateQtrClockwise => RotateQtrClockwise_PointType
!> @copybrief GeomPoints::coord2str_PointType
!> @copydetails GeomPoints::coord2str_PointType
PROCEDURE,PASS :: getCoordString => coord2str_PointType
......@@ -257,6 +261,23 @@ ELEMENTAL SUBROUTINE clear_PointType(p)
ENDSUBROUTINE clear_PointType
!
!-------------------------------------------------------------------------------
!> @brief Routine rotates the x-y coordinates of a point type variable @nrot number
!> of clockwise quarter rotations.
!> @param p the point type variable to rotate
!> @param nrot the number of clockwise quarter rotations.
!>
!> @note: Values from [-3,-1] will be handled as well, even though they
!> represent counter clockwise rotations. This will only work for 2-D or
!> greater point dimensions.
ELEMENTAL SUBROUTINE RotateQtrClockwise_PointType(p,nrot)
CLASS(PointType),INTENT(INOUT) :: p
INTEGER(SIK),INTENT(IN) :: nrot
IF(ALLOCATED(p%coord) .AND. p%dim >= 2) &
CALL RotateQtrClockwise(p%coord(1),p%coord(2),nrot)
ENDSUBROUTINE RotateQtrClockwise_PointType
!
!-------------------------------------------------------------------------------
!> @brief Defines the addition operation between two points e.g. @c p=p0+p1
!> @param p0 the first point
!> @param p1 the second point
......
......@@ -23,6 +23,7 @@ USE Futility_DBC
USE IntrType
USE Allocs
USE Constants_Conversion
USE ExtendedMath
USE Geom_Graph
USE Geom_Points
USE Geom_Line
......@@ -36,6 +37,7 @@ PRIVATE
PUBLIC :: PolygonType
PUBLIC :: Polygonize
PUBLIC :: ASSIGNMENT(=)
PUBLIC :: OPERATOR(==)
!> @brief Type used to describe a polygon.
......@@ -150,12 +152,22 @@ ENDINTERFACE
! MODULE PROCEDURE point_inside_PolygonType
!ENDINTERFACE
!> @brief
!> @brief Overloads the Fortran intrinsic operator for comparing
!> two variables to see if they are equal
INTERFACE OPERATOR(==)
!> @copybrief Geom_Poly::isequal_PolygonType
!> @copydetails Geom_Poly::isequal_PolygonType
MODULE PROCEDURE isequal_PolygonType
ENDINTERFACE
!> @brief Overloads the assignment operator.
!>
!> This is so new polygeom types can be assigned to each other.
INTERFACE ASSIGNMENT(=)
!> @copybrief Geom_Poly::assign_PolygonType
!> @copydetails Geom_Poly::assign_PolygonType
MODULE PROCEDURE assign_PolygonType
ENDINTERFACE
!
!===============================================================================
CONTAINS
......@@ -250,6 +262,9 @@ SUBROUTINE set_PolygonType(thisPoly,thatGraph)
ENDSUBROUTINE set_PolygonType
!
!-------------------------------------------------------------------------------
!> @brief This routine calculates the area of an initialized polygon.
!> @param thisPoly The polygon type of which to calculate the area.
!>
SUBROUTINE calcArea(this)
CLASS(PolygonType),INTENT(INOUT) :: this
!
......@@ -315,6 +330,9 @@ SUBROUTINE calcArea(this)
ENDSUBROUTINE calcArea
!
!-------------------------------------------------------------------------------
!> @brief This routine calculates the centroid of an initialized polygon.
!> @param thisPoly The polygon type of which to calculate the centroid.
!>
SUBROUTINE calcCentroid(this)
CLASS(PolygonType),INTENT(INOUT) :: this
!
......@@ -424,8 +442,13 @@ SUBROUTINE clear_PolygonType(thisPolygon)
ENDSUBROUTINE clear_PolygonType
!
!-------------------------------------------------------------------------------
!> @brief
!> @param
!> @brief This function checks if a polygon has any associated polygon
!> subregions. If it does not have any, they polygon type is simple
!> (e.g. a circle, square, triangle, etc...). An example of a non-simple
!> polygon would be concentric circles, where the smaller circle is the
!> subregion of the larger one.
!> @param thisPoly The polygon type to query if it is simple or not.
!> @param bool The logical result of if the polygon is simple.
!>
ELEMENTAL FUNCTION isSimple_PolygonType(thisPoly) RESULT(bool)
CLASS(PolygonType),INTENT(IN) :: thisPoly
......@@ -1355,8 +1378,12 @@ FUNCTION doesPolyIntersect_PolygonType(thisPoly,thatPoly) RESULT(bool)
ENDFUNCTION doesPolyIntersect_PolygonType
!
!-------------------------------------------------------------------------------
!> @brief
!> @param
!> @brief This subroutine calculates the points where a given line intersects
!> with a given polygon. If there is no intersection, points is returned
!> unallocated.
!> @param thisPolygon The polygon type to be intersected.
!> @param line The line type to intersect with the polygon.
!> @param points The point types of the intersection with the polygon.
!>
SUBROUTINE intersectLine_PolygonType(thisPolygon,line,points)
CLASS(PolygonType),INTENT(IN) :: thisPolygon
......@@ -1499,8 +1526,12 @@ SUBROUTINE intersectLine_PolygonType(thisPolygon,line,points)
ENDSUBROUTINE intersectLine_PolygonType
!
!-------------------------------------------------------------------------------
!> @brief
!> @param
!> @brief This subroutine calculates the points where a given polygon intersects
!> with another given polygon. If there is no intersection, points is
!> returned unallocated.
!> @param thisPoly The polygon type to be intersected.
!> @param thatPoly The polygon type to intersect with the polygon.
!> @param points The point types of the intersection with the polygon.
!>
SUBROUTINE intersectPoly_PolygonType(thisPoly,thatPoly,points)
CLASS(PolygonType),INTENT(IN) :: thisPoly
......@@ -1652,8 +1683,12 @@ SUBROUTINE intersectPoly_PolygonType(thisPoly,thatPoly,points)
ENDSUBROUTINE intersectPoly_PolygonType
!
!-------------------------------------------------------------------------------
!> @brief
!> @param
!> @brief This routine subtracts the area of an initialized contained (bound)
!> sub polygon from a containing polygon.
!> @param thisPoly The containing (bounding) polygon type from which to subtract
!> the area.
!> @param thatPoly The contained (bound) polygon type whose area will be used to
!> subtract from the containing polygon.
!>
SUBROUTINE subtractSubVolume_PolygonType(thisPoly,subPoly)
CLASS(PolygonType),INTENT(INOUT) :: thisPoly
......@@ -2003,6 +2038,38 @@ RECURSIVE FUNCTION isequal_PolygonType(p1,p2) RESULT(bool)
ENDFUNCTION isequal_PolygonType
!
!-------------------------------------------------------------------------------
!> @brief An overloaded operator routine to assign one polygon type to another.
!> @param p1 The target polygon type to assign to.
!> @param p2 The source polygon type to assign from.
!>
!> Note: The pointer assignments are shallow copies only. The clear routine
!> will only nullify a polygon, not deallocate an allocated pointer.
!>
SUBROUTINE assign_PolygonType(p1,p2)
TYPE(PolygonType),INTENT(INOUT) :: p1
TYPE(PolygonType),INTENT(IN) :: p2
CALL p1%clear()
IF(p2%isinit) THEN
p1%isInit=p2%isInit
p1%area=p2%area
p1%nVert=p2%nVert
p1%nQuadEdge=p2%nQuadEdge
p1%centroid=p2%centroid
ALLOCATE(p1%vert(p2%nVert))
ALLOCATE(p1%edge(2,p2%nVert))
p1%vert=p2%vert
p1%edge=p2%edge
ALLOCATE(p1%quad2edge(p2%nQuadEdge))
ALLOCATE(p1%quadEdge(3,p2%nQuadEdge))
p1%quad2edge=p2%quad2edge
p1%quadEdge=p2%quadEdge
p1%nextPoly => p2%nextPoly
p1%subRegions => p2%subRegions
ENDIF
ENDSUBROUTINE assign_PolygonType
!
!-------------------------------------------------------------------------------
!> @brief This is a local subroutine to create an arc-circle from a specified
!> quadratic edge for a given polygon type
!> @param thisPoly The polygon type from which to create the arc-circle
......@@ -2095,54 +2162,24 @@ FUNCTION rotateClockwise(this,nrotations) RESULT(new)
!If the user asked for a negative number of rotations or more than 3, shift
!it to a reasonable number
nrot=nrotations
DO WHILE(nrot < 0)
nrot=nrot+4
ENDDO
DO WHILE(nrot > 3)
nrot=nrot-4
ENDDO
SELECTCASE(MOD(nrotations,4))
CASE(0)
nrot=0
CASE(1,-3)
nrot=1
CASE(2,-2)
nrot=2
CASE(3,-1)
nrot=3
ENDSELECT
!0 rotations means we don't actually need to do anything
IF(nrot == 0) RETURN
DO i=1,this%nVert
!Get the old vertex position
x=this%vert(i)%coord(1)
y=this%vert(i)%coord(2)
!Now rotate
DO irot=1,nrot
tmpx=y
tmpy=-x
!Store the current values for the next rotation
x=tmpx
y=tmpy
ENDDO !irot
new%vert(i)%coord(1)=x
new%vert(i)%coord(2)=y
ENDDO !i
DO i=1,this%nQuadEdge
new%quad2edge(i)=this%quad2edge(i)
!Get the old vertex position
x=this%quadEdge(1,i)
y=this%quadEdge(2,i)
!Now rotate
DO irot=1,nrot
tmpx=y
tmpy=-x
!Store the current values for the next rotation
x=tmpx
y=tmpy
ENDDO !irot
new%quadEdge(1,i)=x
new%quadEdge(2,i)=y
new%quadEdge(3,i)=this%quadEdge(3,i)
ENDDO !i
CALL new%vert%RotateQtrClockwise(nrot)
CALL RotateQtrClockwise(new%quadEdge(1,:),new%quadEdge(2,:),nrot)
new%quadEdge(3,:)=this%quadEdge(3,:)
CALL new%calcCentroid()
......
......@@ -22,6 +22,7 @@ REGISTER_SUBTEST('Rational Fraction',testRatFrac)
REGISTER_SUBTEST('GCD',testGCD)
REGISTER_SUBTEST('GCD',testLCM)
REGISTER_SUBTEST('ATAN2PI',testATAN2PI)
REGISTER_SUBTEST('RotateQtrClockwise',testRotateQtrClockwise)
FINALIZE_TEST()
!
......@@ -144,6 +145,101 @@ SUBROUTINE testATAN2PI()
ENDSUBROUTINE testATAN2PI
!
!-------------------------------------------------------------------------------
SUBROUTINE testRotateQtrClockwise()
REAL(SRK) :: x,y
!Null point, no rotation
x=0.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,0)
ASSERT_APPROXEQ(x, 0.0_SRK,'x=0.0 rot 0')
ASSERT_APPROXEQ(y, 0.0_SRK,'y=0.0 rot 0')
!No rotation
x=1.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,0)
ASSERT_APPROXEQ(x, 1.0_SRK,'x=1.0 rot 0')
ASSERT_APPROXEQ(y, 0.0_SRK,'y=0.0 rot 0')
!Rotate 90 degrees CW
x=1.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,1)
ASSERT_APPROXEQ(x, 0.0_SRK,'x=0.0 rot 1')
ASSERT_APPROXEQ(y, -1.0_SRK,'y=-1.0 rot 1')
!Rotate 270 degrees CCW
x=1.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,-3)
ASSERT_APPROXEQ(x, 0.0_SRK,'x=0.0 rot -3')
ASSERT_APPROXEQ(y, -1.0_SRK,'y=-1.0 rot -3')
!Rotate 180 degrees CW
x=1.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,2)
ASSERT_APPROXEQ(x, -1.0_SRK,'x=-1.0 rot 2')
ASSERT_APPROXEQ(y, 0.0_SRK,'y=0.0 rot 2')
!Rotate 180 degrees CCW
x=1.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,-2)
ASSERT_APPROXEQ(x, -1.0_SRK,'x=-1.0 rot -2')
ASSERT_APPROXEQ(y, 0.0_SRK,'y=0.0 rot -2')
!Rotate 270 degrees CW
x=1.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,3)
ASSERT_APPROXEQ(x, 0.0_SRK,'x=0.0 rot 3')
ASSERT_APPROXEQ(y, 1.0_SRK,'y=1.0 rot 3')
!Rotate 90 degrees CCW
x=1.0_SRK; y=0.0_SRK
CALL RotateQtrClockwise(x,y,-1)
ASSERT_APPROXEQ(x, 0.0_SRK,'x=0.0 rot -1')
ASSERT_APPROXEQ(y, 1.0_SRK,'y=1.0 rot -1')
!No rotation
x=1.0_SRK; y=1.0_SRK
CALL RotateQtrClockwise(x,y,0)
ASSERT_APPROXEQ(x, 1.0_SRK,'x=1.0 rot 0')
ASSERT_APPROXEQ(y, 1.0_SRK,'y=1.0 rot 0')
!Rotate 90 degrees CW
x=1.0_SRK; y=1.0_SRK
CALL RotateQtrClockwise(x,y,1)
ASSERT_APPROXEQ(x, 1.0_SRK,'x=1.0 rot 1')
ASSERT_APPROXEQ(y, -1.0_SRK,'y=-1.0 rot 1')
!Rotate 270 degrees CCW
x=1.0_SRK; y=1.0_SRK
CALL RotateQtrClockwise(x,y,-3)
ASSERT_APPROXEQ(x, 1.0_SRK,'x=1.0 rot -3')
ASSERT_APPROXEQ(y, -1.0_SRK,'y=-1.0 rot -3')
!Rotate 180 degrees CW
x=1.0_SRK; y=1.0_SRK
CALL RotateQtrClockwise(x,y,2)
ASSERT_APPROXEQ(x, -1.0_SRK,'x=-1.0 rot 2')
ASSERT_APPROXEQ(y, -1.0_SRK,'y=-1.0 rot 2')
!Rotate 180 degrees CCW
x=1.0_SRK; y=1.0_SRK
CALL RotateQtrClockwise(x,y,-2)
ASSERT_APPROXEQ(x, -1.0_SRK,'x=-1.0 rot -2')
ASSERT_APPROXEQ(y, -1.0_SRK,'y=-1.0 rot -2')
!Rotate 270 degrees CW
x=1.0_SRK; y=1.0_SRK
CALL RotateQtrClockwise(x,y,3)
ASSERT_APPROXEQ(x, -1.0_SRK,'x=-1.0 rot 3')
ASSERT_APPROXEQ(y, 1.0_SRK,'y=1.0 rot 3')
!Rotate 90 degrees CCW
x=1.0_SRK; y=1.0_SRK
CALL RotateQtrClockwise(x,y,-1)
ASSERT_APPROXEQ(x, -1.0_SRK,'x=-1.0 rot -1')
ASSERT_APPROXEQ(y, 1.0_SRK,'y=1.0 rot -1')
ENDSUBROUTINE testRotateQtrClockwise
!
!-------------------------------------------------------------------------------
FUNCTION oldATAN2PI(x,y) RESULT(theta)
REAL(SRK),INTENT(IN) :: x,y
REAL(SRK) :: theta
......
......@@ -339,7 +339,12 @@ SUBROUTINE TestOBBox
CALL point%init(DIM=2,X=0.0_SRK,Y=-0.5_SRK)
ASSERT(.NOT.box%inside(point),'%hasPoint')
!Test for assignment operation
COMPONENT_TEST('ASSIGNMENT(=)')
box2=box
ASSERT(ALL(box%u == box2%u),'box%u assignment equivalence')
ASSERT(ALL(box%e == box2%e),'box%e assignment equivalence')
ASSERT(box%p0 == box2%p0,'box%p0 assignment equivalence')
!Test for equivalence operation (implicitly tests assignment operation)
COMPONENT_TEST('OPERATOR(==)')
......
......@@ -468,6 +468,15 @@ SUBROUTINE TestCircle_and_Cylinder
CALL point%init(COORD=(/1.7_SRK,1.4_SRK/))
ASSERT(.NOT.circle2%inside(point),'Circle Arc external point Q4')
!
!Test for assignment operation
COMPONENT_TEST('ASSIGNMENT(=)')
circle2=circle1
ASSERT(circle1%c == circle2%c,'circle %c equivalence')
ASSERT(circle1%r == circle2%r,'circle %r equivalence')
ASSERT(circle1%thetastt == circle2%thetastt,'circle %thetastt equivalence')
ASSERT(circle1%thetastp == circle2%thetastp,'circle %thetastp equivalence')
!
!Test for equivalence operation (implicitly tests assignment operation)
COMPONENT_TEST('OPERATOR(==)')
......
......@@ -98,6 +98,118 @@ SUBROUTINE TestPoints
#endif
ASSERT(bool, 'point%getCoordString(...))')
!
!Test RotateQtrClockwise
COMPONENT_TEST('%RotateQtrClockwise()')
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK/)) !test 1-D
CALL point%RotateQtrClockwise(1)
ASSERT_EQ(point%coord(1),1.0_SRK, 'point%RotateQtrClockwise(1) 1-D point')
CALL point%clear()
CALL point%init(COORD=(/1.7_SRK,1.8_SRK,1.9_SRK,1.0_SRK/)) !test N-D
CALL point%RotateQtrClockwise(2)
ASSERT_APPROXEQ(point%coord(1),-1.7_SRK, '%RotateQtrClockwise(2) coord(1) 4-D point')
ASSERT_APPROXEQ(point%coord(2),-1.8_SRK, '%RotateQtrClockwise(2) coord(2) 4-D point')
!No rotation
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,0.0_SRK/))
CALL point%RotateQtrClockwise(0)
ASSERT_APPROXEQ(point%coord(1),1.0_SRK, '%RotateQtrClockwise(0) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),0.0_SRK, '%RotateQtrClockwise(0) coord(2) 2-D point')
!Rotate 90 degrees CW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,0.0_SRK/))
CALL point%RotateQtrClockwise(1)
ASSERT_APPROXEQ(point%coord(1),0.0_SRK, '%RotateQtrClockwise(1) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),-1.0_SRK, '%RotateQtrClockwise(1) coord(2) 2-D point')
!Rotate 270 degrees CCW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,0.0_SRK/))
CALL point%RotateQtrClockwise(-3)
ASSERT_APPROXEQ(point%coord(1),0.0_SRK, '%RotateQtrClockwise(-3) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),-1.0_SRK, '%RotateQtrClockwise(-3) coord(2) 2-D point')
!Rotate 180 degrees CW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,0.0_SRK/))
CALL point%RotateQtrClockwise(2)
ASSERT_APPROXEQ(point%coord(1),-1.0_SRK, '%RotateQtrClockwise(2) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),0.0_SRK, '%RotateQtrClockwise(2) coord(2) 2-D point')
!Rotate 180 degrees CCW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,0.0_SRK/))
CALL point%RotateQtrClockwise(-2)
ASSERT_APPROXEQ(point%coord(1),-1.0_SRK, '%RotateQtrClockwise(-2) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),0.0_SRK, '%RotateQtrClockwise(-2) coord(2) 2-D point')
!Rotate 270 degrees CW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,0.0_SRK/))
CALL point%RotateQtrClockwise(3)
ASSERT_APPROXEQ(point%coord(1),0.0_SRK, '%RotateQtrClockwise(3) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),1.0_SRK, '%RotateQtrClockwise(3) coord(2) 2-D point')
!Rotate 90 degrees CCW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,0.0_SRK/))
CALL point%RotateQtrClockwise(-1)
ASSERT_APPROXEQ(point%coord(1),0.0_SRK, '%RotateQtrClockwise(-1) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),1.0_SRK, '%RotateQtrClockwise(-1) coord(2) 2-D point')
!No rotation
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,1.0_SRK/))
CALL point%RotateQtrClockwise(0)
ASSERT_APPROXEQ(point%coord(1),1.0_SRK, '%RotateQtrClockwise(0) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),1.0_SRK, '%RotateQtrClockwise(0) coord(2) 2-D point')
!Rotate 90 degrees CW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,1.0_SRK/))
CALL point%RotateQtrClockwise(1)
ASSERT_APPROXEQ(point%coord(1),1.0_SRK, '%RotateQtrClockwise(1) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),-1.0_SRK, '%RotateQtrClockwise(1) coord(2) 2-D point')
!Rotate 270 degrees CCW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,1.0_SRK/))
CALL point%RotateQtrClockwise(-3)
ASSERT_APPROXEQ(point%coord(1),1.0_SRK, '%RotateQtrClockwise(-3) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),-1.0_SRK, '%RotateQtrClockwise(-3) coord(2) 2-D point')
!Rotate 180 degrees CW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,1.0_SRK/))
CALL point%RotateQtrClockwise(2)
ASSERT_APPROXEQ(point%coord(1),-1.0_SRK, '%RotateQtrClockwise(2) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),-1.0_SRK, '%RotateQtrClockwise(2) coord(2) 2-D point')
!Rotate 180 degrees CCW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,1.0_SRK/))
CALL point%RotateQtrClockwise(-2)
ASSERT_APPROXEQ(point%coord(1),-1.0_SRK, '%RotateQtrClockwise(-2) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),-1.0_SRK, '%RotateQtrClockwise(-2) coord(2) 2-D point')
!Rotate 270 degrees CW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,1.0_SRK/))
CALL point%RotateQtrClockwise(3)
ASSERT_APPROXEQ(point%coord(1),-1.0_SRK, '%RotateQtrClockwise(3) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),1.0_SRK, '%RotateQtrClockwise(3) coord(2) 2-D point')
!Rotate 90 degrees CCW
CALL point%clear()
CALL point%init(COORD=(/1.0_SRK,1.0_SRK/))
CALL point%RotateQtrClockwise(-1)
ASSERT_APPROXEQ(point%coord(1),-1.0_SRK, '%RotateQtrClockwise(-1) coord(1) 2-D point')
ASSERT_APPROXEQ(point%coord(2),1.0_SRK, '%RotateQtrClockwise(-1) coord(2) 2-D point')
!
!Test Distance
COMPONENT_TEST('Distance()')
CALL point2%init(DIM=1,X=0.5_SRK)
......
......@@ -48,6 +48,7 @@ REGISTER_SUBTEST('%boundsPoly',testPolyInside)
REGISTER_SUBTEST('%doesPolyIntersect',testDoesPolyIntersect)
REGISTER_SUBTEST('%subtractSubVolume',testSubtractSubVol)
REGISTER_SUBTEST('Operator(==)',testEquivalence)
REGISTER_SUBTEST('Assignment(=)',testAssignment)
REGISTER_SUBTEST('RotateClockwise',testRotateClockwise)