diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index dac9e727..7150a72e 100755 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -143,6 +143,7 @@ ADD_CUSTOM_COMMAND (OUTPUT ${OUTPUT} COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/tools/python/Library/__init__.py" "${CMAKE_CURRENT_BINARY_DIR}/Library/__init__.py" COMMAND cp "${CMAKE_CURRENT_SOURCE_DIR}/tools/python/${PROJECT_PATH}/__init__.py" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/__init__.py" COMMAND cp "/usr/local/lib/libboost_python36.so.1.68.0" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/libboost_python36.so.1.68.0" + COMMAND cp "/usr/local/lib/libboost_numpy36.so.1.68.0" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/libboost_numpy36.so.1.68.0" COMMAND cp "${CMAKE_SOURCE_DIR}/lib/${SHARED_LIBRARY_TARGET}" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/liblibrary-mathematics.so.0" COMMAND cp "${CMAKE_SOURCE_DIR}/lib/${LIBRARY_TARGET}" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/LibraryMathematicsPy.so" COMMAND ${PYTHON} ${SETUP_PY} bdist_wheel diff --git a/bindings/python/docs/Reference/Geometry.ipynb b/bindings/python/docs/Reference/Geometry.ipynb index 458fef86..24574b34 100644 --- a/bindings/python/docs/Reference/Geometry.ipynb +++ b/bindings/python/docs/Reference/Geometry.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -27,7 +27,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -46,7 +46,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -65,7 +65,9 @@ "Sphere = Mathematics.Geometry.D3.Objects.Sphere\n", "Ellipsoid = Mathematics.Geometry.D3.Objects.Ellipsoid\n", "Transformation3d = Mathematics.Geometry.D3.Transformation\n", - "Quaternion = Mathematics.Geometry.D3.Transformations.Rotations.Quaternion" + "Quaternion = Mathematics.Geometry.D3.Transformations.Rotations.Quaternion\n", + "RotationVector = Mathematics.Geometry.D3.Transformations.Rotations.RotationVector\n", + "RotationMatrix = Mathematics.Geometry.D3.Transformations.Rotations.RotationMatrix" ] }, { @@ -98,7 +100,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -120,7 +122,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -144,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -153,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -162,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -177,7 +179,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -208,7 +210,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -217,7 +219,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -226,7 +228,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -235,7 +237,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -251,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -261,7 +263,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -271,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -287,7 +289,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -296,7 +298,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -326,7 +328,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -335,7 +337,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 21, "metadata": {}, "outputs": [], "source": [ @@ -344,7 +346,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -353,7 +355,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -369,7 +371,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -379,7 +381,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -389,7 +391,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -405,7 +407,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -414,7 +416,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -437,7 +439,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -446,7 +448,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -462,7 +464,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -472,7 +474,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -488,7 +490,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -497,7 +499,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -506,7 +508,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -515,7 +517,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -524,7 +526,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -533,7 +535,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ @@ -584,7 +586,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -593,7 +595,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 40, "metadata": {}, "outputs": [], "source": [ @@ -609,7 +611,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ @@ -626,7 +628,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ @@ -635,7 +637,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 43, "metadata": {}, "outputs": [], "source": [ @@ -644,7 +646,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ @@ -653,7 +655,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 45, "metadata": {}, "outputs": [], "source": [ @@ -662,7 +664,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ @@ -672,7 +674,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 47, "metadata": {}, "outputs": [], "source": [ @@ -681,7 +683,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -690,7 +692,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ @@ -699,7 +701,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 50, "metadata": {}, "outputs": [], "source": [ @@ -750,7 +752,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 51, "metadata": {}, "outputs": [], "source": [ @@ -763,7 +765,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 52, "metadata": {}, "outputs": [], "source": [ @@ -779,7 +781,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 53, "metadata": {}, "outputs": [], "source": [ @@ -796,7 +798,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 54, "metadata": {}, "outputs": [], "source": [ @@ -805,7 +807,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 55, "metadata": {}, "outputs": [], "source": [ @@ -814,7 +816,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 56, "metadata": {}, "outputs": [], "source": [ @@ -823,7 +825,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 57, "metadata": {}, "outputs": [], "source": [ @@ -832,7 +834,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 58, "metadata": {}, "outputs": [], "source": [ @@ -841,7 +843,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 59, "metadata": {}, "outputs": [], "source": [ @@ -850,7 +852,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 60, "metadata": {}, "outputs": [], "source": [ @@ -859,7 +861,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 61, "metadata": {}, "outputs": [], "source": [ @@ -870,7 +872,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 62, "metadata": {}, "outputs": [], "source": [ @@ -881,7 +883,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 63, "metadata": {}, "outputs": [], "source": [ @@ -890,7 +892,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 64, "metadata": {}, "outputs": [], "source": [ @@ -913,7 +915,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 65, "metadata": {}, "outputs": [], "source": [ @@ -922,7 +924,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 66, "metadata": {}, "outputs": [], "source": [ @@ -931,7 +933,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 67, "metadata": {}, "outputs": [], "source": [ @@ -947,7 +949,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 68, "metadata": {}, "outputs": [], "source": [ @@ -964,7 +966,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 69, "metadata": {}, "outputs": [], "source": [ @@ -973,7 +975,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 70, "metadata": {}, "outputs": [], "source": [ @@ -982,7 +984,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 71, "metadata": {}, "outputs": [], "source": [ @@ -991,7 +993,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 72, "metadata": {}, "outputs": [], "source": [ @@ -1000,7 +1002,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 73, "metadata": {}, "outputs": [], "source": [ @@ -1023,7 +1025,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 74, "metadata": {}, "outputs": [], "source": [ @@ -1032,7 +1034,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 75, "metadata": {}, "outputs": [], "source": [ @@ -1048,7 +1050,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 76, "metadata": {}, "outputs": [], "source": [ @@ -1065,7 +1067,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 77, "metadata": {}, "outputs": [], "source": [ @@ -1074,7 +1076,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 78, "metadata": {}, "outputs": [], "source": [ @@ -1083,7 +1085,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 79, "metadata": {}, "outputs": [], "source": [ @@ -1092,7 +1094,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 80, "metadata": {}, "outputs": [], "source": [ @@ -1101,7 +1103,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 81, "metadata": {}, "outputs": [], "source": [ @@ -1110,7 +1112,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 82, "metadata": {}, "outputs": [], "source": [ @@ -1119,7 +1121,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 83, "metadata": {}, "outputs": [], "source": [ @@ -1128,7 +1130,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 84, "metadata": {}, "outputs": [], "source": [ @@ -1137,7 +1139,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 85, "metadata": {}, "outputs": [], "source": [ @@ -1146,7 +1148,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 86, "metadata": {}, "outputs": [], "source": [ @@ -1155,7 +1157,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 87, "metadata": {}, "outputs": [], "source": [ @@ -1164,7 +1166,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 88, "metadata": {}, "outputs": [], "source": [ @@ -1175,7 +1177,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 89, "metadata": {}, "outputs": [], "source": [ @@ -1186,7 +1188,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 90, "metadata": {}, "outputs": [], "source": [ @@ -1195,7 +1197,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 91, "metadata": {}, "outputs": [], "source": [ @@ -1204,7 +1206,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 92, "metadata": {}, "outputs": [], "source": [ @@ -1213,7 +1215,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 93, "metadata": {}, "outputs": [], "source": [ @@ -1223,7 +1225,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 94, "metadata": {}, "outputs": [], "source": [ @@ -1232,7 +1234,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 95, "metadata": {}, "outputs": [], "source": [ @@ -1309,19 +1311,66 @@ "**Geometry ▸ Transformations ▸ Rotations ▸ Quaternion ▸ Constructors**" ] }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [], + "source": [ + "quaternion = Quaternion(0.0, 0.0, 0.0, 1.0, Quaternion.Format.XYZS) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [], + "source": [ + "quaternion = Quaternion.Undefined() ;" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": {}, + "outputs": [], + "source": [ + "quaternion = Quaternion.Unit() ;" + ] + }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [], "source": [ - "quaternion = Quaternion(0.0, 0.0, 0.0, 1.0, Quaternion.Format.XYZS)\n", - "\n", - "quaternion = Quaternion.Undefined()\n", - "quaternion = Quaternion.Unit()\n", - "quaternion = Quaternion.XYZS(0.0, 0.0, 0.0, 1.0)\n", - "# quaternion = Quaternion.RotationVector\n", - "# quaternion = Quaternion.RotationMatrix\n", + "quaternion = Quaternion.XYZS(0.0, 0.0, 0.0, 1.0) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [], + "source": [ + "quaternion = Quaternion.RotationVector(RotationVector.Unit()) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [], + "source": [ + "quaternion = Quaternion.RotationMatrix(RotationMatrix.Unit()) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": {}, + "outputs": [], + "source": [ "quaternion = Quaternion.Parse(\"[0.0, 0.0, 0.0, 1.0]\", Quaternion.Format.XYZS)" ] }, @@ -1334,7 +1383,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 103, "metadata": {}, "outputs": [], "source": [ @@ -1356,7 +1405,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 104, "metadata": {}, "outputs": [], "source": [ @@ -1365,7 +1414,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 105, "metadata": {}, "outputs": [], "source": [ @@ -1374,7 +1423,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 106, "metadata": {}, "outputs": [], "source": [ @@ -1383,7 +1432,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 107, "metadata": {}, "outputs": [], "source": [ @@ -1395,7 +1444,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 108, "metadata": {}, "outputs": [], "source": [ @@ -1405,7 +1454,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 109, "metadata": {}, "outputs": [], "source": [ @@ -1414,7 +1463,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 110, "metadata": {}, "outputs": [], "source": [ @@ -1423,7 +1472,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 111, "metadata": {}, "outputs": [], "source": [ @@ -1432,7 +1481,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 112, "metadata": {}, "outputs": [], "source": [ @@ -1444,7 +1493,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 113, "metadata": {}, "outputs": [], "source": [ @@ -1453,7 +1502,7 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": 114, "metadata": {}, "outputs": [], "source": [ @@ -1462,7 +1511,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 115, "metadata": {}, "outputs": [], "source": [ @@ -1471,7 +1520,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 116, "metadata": {}, "outputs": [], "source": [ @@ -1480,7 +1529,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 117, "metadata": {}, "outputs": [], "source": [ @@ -1489,7 +1538,7 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 118, "metadata": {}, "outputs": [], "source": [ @@ -1498,7 +1547,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 119, "metadata": {}, "outputs": [], "source": [ @@ -1507,7 +1556,7 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 120, "metadata": {}, "outputs": [], "source": [ @@ -1516,7 +1565,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 121, "metadata": {}, "outputs": [], "source": [ @@ -1539,10 +1588,75 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 122, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "rotation_vector = RotationVector(numpy.array((0.0, 0.0, 1.0)), Angle.Degrees(45.0)) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": {}, + "outputs": [], + "source": [ + "RotationVector.Undefined() ;" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": {}, + "outputs": [], + "source": [ + "RotationVector.Unit() ;" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "metadata": {}, + "outputs": [], + "source": [ + "RotationVector.X(Angle.Degrees(45.0)) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": {}, + "outputs": [], + "source": [ + "RotationVector.Y(Angle.Degrees(45.0)) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": {}, + "outputs": [], + "source": [ + "RotationVector.Z(Angle.Degrees(45.0)) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": {}, + "outputs": [], + "source": [ + "RotationVector.Quaternion(Quaternion.Unit()) ;" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": {}, + "outputs": [], + "source": [ + "RotationVector.RotationMatrix(RotationMatrix.Unit()) ;" + ] }, { "cell_type": "markdown", @@ -1553,10 +1667,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 130, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "rotation_vector == rotation_vector ;\n", + "rotation_vector != rotation_vector ;" + ] }, { "cell_type": "markdown", @@ -1567,10 +1684,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 131, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "rotation_vector.isDefined() ;" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": {}, + "outputs": [], + "source": [ + "rotation_vector.getAxis() ;\n", + "rotation_vector.getAngle() ;" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": {}, + "outputs": [], + "source": [ + "rotation_vector.toString() ;\n", + "rotation_vector.toString(3) ;" + ] }, { "cell_type": "markdown", diff --git a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects.cpp b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects.cpp index fe8a65e1..93e5ad37 100755 --- a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects.cpp +++ b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects.cpp @@ -8,8 +8,8 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include +#include #include -// #include #include #include #include @@ -46,6 +46,7 @@ inline void LibraryMathematicsPy_Geometry_3D_Objects ( ) LibraryMathematicsPy_Geometry_3D_Objects_Sphere() ; LibraryMathematicsPy_Geometry_3D_Objects_Ellipsoid() ; LibraryMathematicsPy_Geometry_3D_Objects_Pyramid() ; + LibraryMathematicsPy_Geometry_3D_Objects_Cone() ; LibraryMathematicsPy_Geometry_3D_Objects_Composite() ; } diff --git a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects/Cone.cpp b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects/Cone.cpp new file mode 100755 index 00000000..05668277 --- /dev/null +++ b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects/Cone.cpp @@ -0,0 +1,65 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// @project Library/Mathematics +/// @file LibraryMathematicsPy/Geometry/3D/Objects/Cone.cpp +/// @author Lucas Brémond +/// @license TBD + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void LibraryMathematicsPy_Geometry_3D_Objects_Cone ( ) +{ + + using namespace boost::python ; + + using library::core::types::Size ; + using library::core::types::Real ; + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::Object ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::PointSet ; + using library::math::geom::d3::objects::Line ; + using library::math::geom::d3::objects::Ray ; + using library::math::geom::d3::objects::Segment ; + using library::math::geom::d3::objects::Plane ; + using library::math::geom::d3::objects::Polygon ; + using library::math::geom::d3::objects::Sphere ; + using library::math::geom::d3::objects::Ellipsoid ; + using library::math::geom::d3::objects::Cone ; + using library::math::geom::d3::Intersection ; + + scope in_Cone = class_>("Cone", init()) + + .def(self == self) + .def(self != self) + + .def(self_ns::str(self_ns::self)) + .def(self_ns::repr(self_ns::self)) + + .def("isDefined", &Cone::isDefined) + .def("intersectsEllipsoid", +[] (const Cone& aCone, const Ellipsoid& anEllipsoid) -> bool { return aCone.intersects(anEllipsoid) ; }) + .def("intersectsEllipsoid", +[] (const Cone& aCone, const Ellipsoid& anEllipsoid, const Size aDiscretizationLevel) -> bool { return aCone.intersects(anEllipsoid, aDiscretizationLevel) ; }) + + .def("getApex", &Cone::getApex) + .def("getAxis", &Cone::getAxis) + .def("getAngle", &Cone::getAngle) + .def("getRaysOfLateralSurface", &Cone::getRaysOfLateralSurface) + .def("intersectionWithEllipsoid", +[] (const Cone& aCone, const Ellipsoid& anEllipsoid) -> Intersection { return aCone.intersectionWith(anEllipsoid) ; }) + .def("intersectionWithEllipsoid", +[] (const Cone& aCone, const Ellipsoid& anEllipsoid, const bool onlyInSight) -> Intersection { return aCone.intersectionWith(anEllipsoid, onlyInSight) ; }) + .def("intersectionWithEllipsoid", +[] (const Cone& aCone, const Ellipsoid& anEllipsoid, const bool onlyInSight, const Size aDiscretizationLevel) -> Intersection { return aCone.intersectionWith(anEllipsoid, onlyInSight, aDiscretizationLevel) ; }) + .def("applyTransformation", &Cone::applyTransformation) + + .def("Undefined", &Cone::Undefined).staticmethod("Undefined") + + ; + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects/Pyramid.cpp b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects/Pyramid.cpp index 2ca3fc61..8909d9bc 100755 --- a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects/Pyramid.cpp +++ b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Objects/Pyramid.cpp @@ -43,9 +43,9 @@ inline void LibraryMathematicsPy_Geometry_3D_Objects_Pyramid .def(self_ns::repr(self_ns::self)) .def("isDefined", &Pyramid::isDefined) - .def("intersectsEllipsoid", +[] (const Pyramid& anPyramid, const Ellipsoid& anEllipsoid) -> bool { return anPyramid.intersects(anEllipsoid) ; }) - .def("intersectsEllipsoid", +[] (const Pyramid& anPyramid, const Ellipsoid& anEllipsoid, const Size aDiscretizationLevel) -> bool { return anPyramid.intersects(anEllipsoid, aDiscretizationLevel) ; }) - .def("containsEllipsoid", +[] (const Pyramid& anPyramid, const Ellipsoid& anEllipsoid) -> bool { return anPyramid.contains(anEllipsoid) ; }) + .def("intersectsEllipsoid", +[] (const Pyramid& aPyramid, const Ellipsoid& anEllipsoid) -> bool { return aPyramid.intersects(anEllipsoid) ; }) + .def("intersectsEllipsoid", +[] (const Pyramid& aPyramid, const Ellipsoid& anEllipsoid, const Size aDiscretizationLevel) -> bool { return aPyramid.intersects(anEllipsoid, aDiscretizationLevel) ; }) + .def("containsEllipsoid", +[] (const Pyramid& aPyramid, const Ellipsoid& anEllipsoid) -> bool { return aPyramid.contains(anEllipsoid) ; }) .def("getBase", &Pyramid::getBase) .def("getApex", &Pyramid::getApex) @@ -53,9 +53,9 @@ inline void LibraryMathematicsPy_Geometry_3D_Objects_Pyramid .def("getLateralFaceAt", &Pyramid::getLateralFaceAt) .def("getRaysOfLateralFaceAt", &Pyramid::getRaysOfLateralFaceAt) .def("getRaysOfLateralFaces", &Pyramid::getRaysOfLateralFaces) - .def("intersectionWithEllipsoid", +[] (const Pyramid& anPyramid, const Ellipsoid& anEllipsoid) -> Intersection { return anPyramid.intersectionWith(anEllipsoid) ; }) - .def("intersectionWithEllipsoid", +[] (const Pyramid& anPyramid, const Ellipsoid& anEllipsoid, const bool onlyInSight) -> Intersection { return anPyramid.intersectionWith(anEllipsoid, onlyInSight) ; }) - .def("intersectionWithEllipsoid", +[] (const Pyramid& anPyramid, const Ellipsoid& anEllipsoid, const bool onlyInSight, const Size aDiscretizationLevel) -> Intersection { return anPyramid.intersectionWith(anEllipsoid, onlyInSight, aDiscretizationLevel) ; }) + .def("intersectionWithEllipsoid", +[] (const Pyramid& aPyramid, const Ellipsoid& anEllipsoid) -> Intersection { return aPyramid.intersectionWith(anEllipsoid) ; }) + .def("intersectionWithEllipsoid", +[] (const Pyramid& aPyramid, const Ellipsoid& anEllipsoid, const bool onlyInSight) -> Intersection { return aPyramid.intersectionWith(anEllipsoid, onlyInSight) ; }) + .def("intersectionWithEllipsoid", +[] (const Pyramid& aPyramid, const Ellipsoid& anEllipsoid, const bool onlyInSight, const Size aDiscretizationLevel) -> Intersection { return aPyramid.intersectionWith(anEllipsoid, onlyInSight, aDiscretizationLevel) ; }) .def("applyTransformation", &Pyramid::applyTransformation) .def("Undefined", &Pyramid::Undefined).staticmethod("Undefined") diff --git a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformation.cpp b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformation.cpp index 72a65604..54c4935a 100755 --- a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformation.cpp +++ b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformation.cpp @@ -20,6 +20,7 @@ inline void LibraryMathematicsPy_Geometry_3D_Transformation using library::math::obj::Matrix4d ; using library::math::geom::d3::objects::Point ; using library::math::geom::d3::Transformation ; + using library::math::geom::d3::trf::rot::RotationMatrix ; scope in_Transformation = class_("Transformation", init()) @@ -40,7 +41,9 @@ inline void LibraryMathematicsPy_Geometry_3D_Transformation .def("Undefined", &Transformation::Undefined).staticmethod("Undefined") .def("Identity", &Transformation::Identity).staticmethod("Identity") .def("Translation", &Transformation::Translation).staticmethod("Translation") - .def("Rotation", &Transformation::Rotation).staticmethod("Rotation") + // .def("Rotation", &Transformation::Rotation).staticmethod("Rotation") + // .def("Rotation", +[] (const RotationVector& aRotationVector) -> Transformation { return Transformation::Rotation(aRotationVector) ; } ) + .def("Rotation", +[] (const RotationMatrix& aRotationMatrix) -> Transformation { return Transformation::Rotation(aRotationMatrix) ; } ) .def("RotationAround", &Transformation::RotationAround).staticmethod("RotationAround") .def("StringFromType", &Transformation::StringFromType).staticmethod("StringFromType") diff --git a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformations/Rotations/RotationVector.cpp b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformations/Rotations/RotationVector.cpp index ce1fc9a8..13e94b0e 100755 --- a/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformations/Rotations/RotationVector.cpp +++ b/bindings/python/src/LibraryMathematicsPy/Geometry/3D/Transformations/Rotations/RotationVector.cpp @@ -18,6 +18,7 @@ inline void LibraryMathematicsPy_Geometry_3D_Transformations using namespace boost::python ; + using library::core::types::Integer ; using library::core::types::Real ; using library::core::types::String ; @@ -25,7 +26,7 @@ inline void LibraryMathematicsPy_Geometry_3D_Transformations using library::math::geom::Angle ; using library::math::geom::d3::trf::rot::RotationVector ; - scope in_RotationVector = class_("RotationVector", init()) + scope in_RotationVector = class_("RotationVector", init()) .def(self == self) .def(self != self) @@ -37,10 +38,14 @@ inline void LibraryMathematicsPy_Geometry_3D_Transformations .def("getAxis", &RotationVector::getAxis) .def("getAngle", &RotationVector::getAngle) - .def("toString", &RotationVector::toString) + .def("toString", +[] (const RotationVector& aRotationVector) -> String { return aRotationVector.toString() ; }) + .def("toString", +[] (const RotationVector& aRotationVector, const Integer& aPrecision) -> String { return aRotationVector.toString(aPrecision) ; }) .def("Undefined", &RotationVector::Undefined) .def("Unit", &RotationVector::Unit).staticmethod("Unit") + .def("X", &RotationVector::X).staticmethod("X") + .def("Y", &RotationVector::Y).staticmethod("Y") + .def("Z", &RotationVector::Z).staticmethod("Z") .def("Quaternion", &RotationVector::Quaternion).staticmethod("Quaternion") .def("RotationMatrix", &RotationVector::RotationMatrix).staticmethod("RotationMatrix") diff --git a/bindings/python/tools/python/setup.py.in b/bindings/python/tools/python/setup.py.in index e0325468..6d68d900 100644 --- a/bindings/python/tools/python/setup.py.in +++ b/bindings/python/tools/python/setup.py.in @@ -20,5 +20,5 @@ setuptools.setup( ), keywords="open-space-collective mathematics", packages=setuptools.find_packages(), - package_data={"": ["${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/LibraryMathematicsPy.so", "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/liblibrary-mathematics.so.0", "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/libboost_python36.so.1.68.0"]} + package_data={"": ["${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/LibraryMathematicsPy.so", "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/liblibrary-mathematics.so.0", "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/libboost_python36.so.1.68.0", "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_PATH}/libboost_numpy36.so.1.68.0"]} ) \ No newline at end of file diff --git a/include/Library/Mathematics/Geometry/3D/Objects/Cone.hpp b/include/Library/Mathematics/Geometry/3D/Objects/Cone.hpp new file mode 100755 index 00000000..98cfa6e1 --- /dev/null +++ b/include/Library/Mathematics/Geometry/3D/Objects/Cone.hpp @@ -0,0 +1,229 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// @project Library/Mathematics +/// @file Library/Mathematics/Geometry/3D/Objects/Cone.hpp +/// @author Lucas Brémond +/// @license TBD + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef __Library_Mathematics_Geometry_3D_Objects_Cone__ +#define __Library_Mathematics_Geometry_3D_Objects_Cone__ + +#include +#include +#include + +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace library +{ +namespace math +{ +namespace geom +{ +namespace d3 +{ +namespace objects +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +using library::core::ctnr::Index ; +using library::core::ctnr::Size ; +using library::core::ctnr::Array ; + +using library::math::obj::Vector3d ; +using library::math::geom::Angle ; +using library::math::geom::d3::Object ; +using library::math::geom::d3::objects::Point ; +using library::math::geom::d3::objects::Ray ; +using library::math::geom::d3::Intersection ; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class Line ; +class Segment ; +class Plane ; +class Polygon ; +class Sphere ; +class Ellipsoid ; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// @brief Cone +/// +/// A cone is a three-dimensional geometric shape that tapers smoothly from a flat circular base to a point called the apex. +/// +/// @ref https://en.wikipedia.org/wiki/Cone + +class Cone : public Object +{ + + public: + + /// @brief Constructor + /// + /// @code + /// Point apex = { 0.0, 0.0, 0.0 } ; + /// Vector3d axis = { 0.0, 0.0, 1.0 } ; + /// Angle angle = Angle::Degrees(15.0) ; + /// Cone cone = { apex, axis, angle } ; + /// @endcode + /// + /// @param [in] anApex A cone apex + /// @param [in] anAxis A cone axis + /// @param [in] anAngle A cone angle + + Cone ( const Point& anApex, + const Vector3d& anAxis, + const Angle& anAngle ) ; + + /// @brief Clone cone + /// + /// @return Pointer to cloned cone + + virtual Cone* clone ( ) const override ; + + /// @brief Equal to operator + /// + /// @param [in] aCone A cone + /// @return True if cones are equal + + bool operator == ( const Cone& aCone ) const ; + + /// @brief Not equal to operator + /// + /// @param [in] aCone A cone + /// @return True if cones are not equal + + bool operator != ( const Cone& aCone ) const ; + + /// @brief Check if cone is defined + /// + /// @return True if cone is defined + + virtual bool isDefined ( ) const override ; + + /// @brief Check if cone intersects sphere + /// + /// @code + /// Cone cone = ... ; + /// Sphere sphere = ... ; + /// cone.intersects(sphere) ; + /// @endcode + /// + /// @param [in] aSphere A sphere + /// @param [in] aDiscretizationLevel (optional) The polygonal discretization level + /// @return True if cone intersects sphere + + bool intersects ( const Sphere& aSphere, + const Size aDiscretizationLevel = 40 ) const ; + + /// @brief Check if cone intersects ellipsoid + /// + /// @code + /// Cone cone = ... ; + /// Ellipsoid ellipsoid = ... ; + /// cone.intersects(ellipsoid) ; + /// @endcode + /// + /// @param [in] anEllipsoid An ellipsoid + /// @param [in] aDiscretizationLevel (optional) The polygonal discretization level + /// @return True if cone intersects ellipsoid + + bool intersects ( const Ellipsoid& anEllipsoid, + const Size aDiscretizationLevel = 40 ) const ; + + /// @brief Get cone apex + /// + /// @return Cone apex + + Point getApex ( ) const ; + + /// @brief Get cone axis + /// + /// @return Cone axis + + Vector3d getAxis ( ) const ; + + /// @brief Get cone angle + /// + /// @return Cone angle + + Angle getAngle ( ) const ; + + /// @brief Get rays of lateral surface + /// + /// @param [in] aRayCount A number of rays (at least face count) + /// @return Array of rays + + Array getRaysOfLateralSurface ( const Size aRayCount = 0 ) const ; + + /// @brief Compute intersection of cone with sphere + /// + /// @param [in] aSphere A sphere + /// @param [in] onlyInSight (optional) If true, only return intersection points that are in sight + /// @param [in] aDiscretizationLevel (optional) The polygonal discretization level + /// @return Intersection of cone with sphere + + Intersection intersectionWith ( const Sphere& aSphere, + const bool onlyInSight = false, + const Size aDiscretizationLevel = 40 ) const ; + + /// @brief Compute intersection of cone with ellipsoid + /// + /// @param [in] anEllipsoid An ellipsoid + /// @param [in] onlyInSight (optional) If true, only return intersection points that are in sight + /// @param [in] aDiscretizationLevel (optional) The polygonal discretization level + /// @return Intersection of cone with ellipsoid + + Intersection intersectionWith ( const Ellipsoid& anEllipsoid, + const bool onlyInSight = false, + const Size aDiscretizationLevel = 40 ) const ; + + /// @brief Print cone + /// + /// @param [in] anOutputStream An output stream + /// @param [in] (optional) displayDecorators If true, display decorators + + virtual void print ( std::ostream& anOutputStream, + bool displayDecorators = true ) const override ; + + /// @brief Apply transformation to cone + /// + /// @param [in] aTransformation A transformation + + virtual void applyTransformation ( const Transformation& aTransformation ) override ; + + /// @brief Constructs an undefined cone + /// + /// @return Undefined cone + + static Cone Undefined ( ) ; + + private: + + Point apex_ ; + Vector3d axis_ ; + Angle angle_ ; + +} ; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +} +} +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/include/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.hpp b/include/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.hpp index 4ab857ea..2de1ff63 100755 --- a/include/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.hpp +++ b/include/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.hpp @@ -49,6 +49,7 @@ class Plane ; class Polygon ; class Sphere ; class Pyramid ; +class Cone ; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -234,6 +235,19 @@ class Ellipsoid : public Object bool intersects ( const Pyramid& aPyramid ) const ; + /// @brief Check if ellipsoid intersects cone + /// + /// @code + /// Ellipsoid ellipsoid = ... ; + /// Cone cone = ... ; + /// ellipsoid.intersects(cone) ; + /// @endcode + /// + /// @param [in] aCone A cone + /// @return True if ellipsoid intersects cone + + bool intersects ( const Cone& aCone ) const ; + /// @brief Check if ellipsoid contains point /// /// @code @@ -383,6 +397,15 @@ class Ellipsoid : public Object Intersection intersectionWith ( const Pyramid& aPyramid, const bool onlyInSight = false ) const ; + /// @brief Compute intersection of ellipsoid with cone + /// + /// @param [in] aCone A cone + /// @param [in] onlyInSight (optional) If true, only return intersection points that are in sight + /// @return Intersection of ellipsoid with cone + + Intersection intersectionWith ( const Cone& aCone, + const bool onlyInSight = false ) const ; + /// @brief Print ellipsoid /// /// @param [in] anOutputStream An output stream diff --git a/include/Library/Mathematics/Geometry/3D/Objects/Sphere.hpp b/include/Library/Mathematics/Geometry/3D/Objects/Sphere.hpp index 5c7dd005..9df9fde1 100755 --- a/include/Library/Mathematics/Geometry/3D/Objects/Sphere.hpp +++ b/include/Library/Mathematics/Geometry/3D/Objects/Sphere.hpp @@ -45,6 +45,7 @@ class Plane ; class Polygon ; class Ellipsoid ; class Pyramid ; +class Cone ; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -223,6 +224,19 @@ class Sphere : public Object bool intersects ( const Pyramid& aPyramid ) const ; + /// @brief Check if sphere intersects cone + /// + /// @code + /// Sphere sphere = ... ; + /// Cone cone = ... ; + /// sphere.intersects(cone) ; + /// @endcode + /// + /// @param [in] aCone A cone + /// @return True if sphere intersects cone + + bool intersects ( const Cone& aCone ) const ; + /// @brief Check if sphere contains point /// /// @code @@ -301,6 +315,15 @@ class Sphere : public Object Intersection intersectionWith ( const Pyramid& aPyramid, const bool onlyInSight = false ) const ; + /// @brief Compute intersection of sphere with cone + /// + /// @param [in] aCone A cone + /// @param [in] onlyInSight (optional) If true, only return intersection points that are in sight + /// @return Intersection of sphere with cone + + Intersection intersectionWith ( const Cone& aCone, + const bool onlyInSight = false ) const ; + /// @brief Print sphere /// /// @param [in] anOutputStream An output stream diff --git a/include/Library/Mathematics/Geometry/3D/Transformation.hpp b/include/Library/Mathematics/Geometry/3D/Transformation.hpp index e8f37a70..f44495c2 100755 --- a/include/Library/Mathematics/Geometry/3D/Transformation.hpp +++ b/include/Library/Mathematics/Geometry/3D/Transformation.hpp @@ -46,6 +46,7 @@ using library::math::geom::Angle ; using library::math::geom::d3::Object ; using library::math::geom::d3::objects::Point ; using library::math::geom::d3::trf::rot::RotationVector ; +using library::math::geom::d3::trf::rot::RotationMatrix ; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -128,6 +129,8 @@ class Transformation static Transformation Rotation ( const RotationVector& aRotationVector ) ; + static Transformation Rotation ( const RotationMatrix& aRotationMatrix ) ; + static Transformation RotationAround ( const Point& aPoint, const RotationVector& aRotationVector ) ; diff --git a/include/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.hpp b/include/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.hpp index da8d12d7..8a896899 100755 --- a/include/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.hpp +++ b/include/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.hpp @@ -151,6 +151,39 @@ class RotationVector static RotationVector Unit ( ) ; + /// @brief Constructs a rotation vector around X-axis + /// + /// @code + /// RotationVector rotationVector = RotationVector::X(Angle::Degrees(45.0)) ; + /// @endcode + /// + /// @param [in] anAngle A rotation angle + /// @return Rotation vector + + static RotationVector X ( const Angle& anAngle ) ; + + /// @brief Constructs a rotation vector around Y-axis + /// + /// @code + /// RotationVector rotationVector = RotationVector::X(Angle::Degrees(45.0)) ; + /// @endcode + /// + /// @param [in] anAngle A rotation angle + /// @return Rotation vector + + static RotationVector Y ( const Angle& anAngle ) ; + + /// @brief Constructs a rotation vector around Z-axis + /// + /// @code + /// RotationVector rotationVector = RotationVector::X(Angle::Degrees(45.0)) ; + /// @endcode + /// + /// @param [in] anAngle A rotation angle + /// @return Rotation vector + + static RotationVector Z ( const Angle& anAngle ) ; + /// @brief Constructs a rotation vector from a quaternion /// /// @code diff --git a/src/Library/Mathematics/Geometry/2D/Transformation.cpp b/src/Library/Mathematics/Geometry/2D/Transformation.cpp index 362571da..25b71886 100644 --- a/src/Library/Mathematics/Geometry/2D/Transformation.cpp +++ b/src/Library/Mathematics/Geometry/2D/Transformation.cpp @@ -288,7 +288,11 @@ void Transformation::print ( displayDecorators ? library::core::utils::Print::Header(anOutputStream, "2D :: Transformation") : void () ; - library::core::utils::Print::Line(anOutputStream) << "Type" << Transformation::StringFromType(type_) ; + library::core::utils::Print::Line(anOutputStream) << "Type:" << Transformation::StringFromType(type_) ; + + library::core::utils::Print::Line(anOutputStream) << "Matrix:" ; + + anOutputStream << matrix_ << std::endl ; displayDecorators ? library::core::utils::Print::Footer(anOutputStream) : void () ; diff --git a/src/Library/Mathematics/Geometry/3D/Object.cpp b/src/Library/Mathematics/Geometry/3D/Object.cpp index bfef887f..0d1cfcd9 100644 --- a/src/Library/Mathematics/Geometry/3D/Object.cpp +++ b/src/Library/Mathematics/Geometry/3D/Object.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -59,6 +60,7 @@ bool Object::operator == ( using library::math::geom::d3::objects::Sphere ; using library::math::geom::d3::objects::Ellipsoid ; using library::math::geom::d3::objects::Pyramid ; + using library::math::geom::d3::objects::Cone ; using library::math::geom::d3::objects::Composite ; if ((!this->isDefined()) || (!anObject.isDefined())) @@ -215,6 +217,18 @@ bool Object::operator == ( } + // Cone + + if (const Cone* objectPtr = dynamic_cast(this)) + { + + if (const Cone* otherObjectPtr = dynamic_cast(&anObject)) + { + return (*objectPtr) == (*otherObjectPtr) ; + } + + } + // Composite if (const Composite* objectPtr = dynamic_cast(this)) @@ -266,6 +280,7 @@ bool Object::intersects ( using library::math::geom::d3::objects::Sphere ; using library::math::geom::d3::objects::Ellipsoid ; using library::math::geom::d3::objects::Pyramid ; + using library::math::geom::d3::objects::Cone ; using library::math::geom::d3::objects::Composite ; if (!anObject.isDefined()) @@ -384,6 +399,13 @@ bool Object::intersects ( return objectPtr->intersects(*otherObjectPtr) ; } + // Cone + + if (const Cone* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersects(*otherObjectPtr) ; + } + } // Ellipsoid @@ -426,6 +448,13 @@ bool Object::intersects ( return objectPtr->intersects(*otherObjectPtr) ; } + // Cone + + if (const Cone* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersects(*otherObjectPtr) ; + } + } // Pyramid @@ -433,6 +462,34 @@ bool Object::intersects ( if (const Pyramid* objectPtr = dynamic_cast(this)) { + // Sphere + + if (const Sphere* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersects(*otherObjectPtr) ; + } + + // Ellipsoid + + if (const Ellipsoid* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersects(*otherObjectPtr) ; + } + + } + + // Cone + + if (const Cone* objectPtr = dynamic_cast(this)) + { + + // Sphere + + if (const Sphere* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersects(*otherObjectPtr) ; + } + // Ellipsoid if (const Ellipsoid* otherObjectPtr = dynamic_cast(&anObject)) @@ -466,6 +523,7 @@ bool Object::contains ( using library::math::geom::d3::objects::Sphere ; using library::math::geom::d3::objects::Ellipsoid ; using library::math::geom::d3::objects::Pyramid ; + using library::math::geom::d3::objects::Cone ; using library::math::geom::d3::objects::Composite ; if (!anObject.isDefined()) @@ -536,6 +594,7 @@ Intersection Object::intersectionWith ( using library::math::geom::d3::objects::Sphere ; using library::math::geom::d3::objects::Ellipsoid ; using library::math::geom::d3::objects::Pyramid ; + using library::math::geom::d3::objects::Cone ; using library::math::geom::d3::objects::Composite ; if (!anObject.isDefined()) @@ -557,6 +616,34 @@ Intersection Object::intersectionWith ( } + // Sphere + + if (const Sphere* objectPtr = dynamic_cast(this)) + { + + // Ray + + if (const Ray* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + + // Pyramid + + if (const Pyramid* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + + // Cone + + if (const Cone* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + + } + // Ellipsoid if (const Ellipsoid* objectPtr = dynamic_cast(this)) @@ -569,6 +656,20 @@ Intersection Object::intersectionWith ( return objectPtr->intersectionWith(*otherObjectPtr) ; } + // Pyramid + + if (const Pyramid* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + + // Cone + + if (const Cone* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + } // Pyramid @@ -576,6 +677,34 @@ Intersection Object::intersectionWith ( if (const Pyramid* objectPtr = dynamic_cast(this)) { + // Sphere + + if (const Sphere* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + + // Ellipsoid + + if (const Ellipsoid* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + + } + + // Cone + + if (const Cone* objectPtr = dynamic_cast(this)) + { + + // Sphere + + if (const Sphere* otherObjectPtr = dynamic_cast(&anObject)) + { + return objectPtr->intersectionWith(*otherObjectPtr) ; + } + // Ellipsoid if (const Ellipsoid* otherObjectPtr = dynamic_cast(&anObject)) diff --git a/src/Library/Mathematics/Geometry/3D/Objects/Cone.cpp b/src/Library/Mathematics/Geometry/3D/Objects/Cone.cpp new file mode 100644 index 00000000..68f811a4 --- /dev/null +++ b/src/Library/Mathematics/Geometry/3D/Objects/Cone.cpp @@ -0,0 +1,409 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// @project Library/Mathematics +/// @file Library/Mathematics/Geometry/3D/Objects/Cone.cpp +/// @author Lucas Brémond +/// @license TBD + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace library +{ +namespace math +{ +namespace geom +{ +namespace d3 +{ +namespace objects +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + Cone::Cone ( const Point& anApex, + const Vector3d& anAxis, + const Angle& anAngle ) + : Object(), + apex_(anApex), + axis_(anAxis), + angle_(anAngle) +{ + +} + +Cone* Cone::clone ( ) const +{ + return new Cone(*this) ; +} + +bool Cone::operator == ( const Cone& aCone ) const +{ + + if ((!this->isDefined()) || (!aCone.isDefined())) + { + return false ; + } + + return (apex_ == aCone.apex_) + && (((axis_ == aCone.axis_) && (angle_ == aCone.angle_)) || ((axis_ == -aCone.axis_) && (angle_ == Angle::Degrees(180.0) - aCone.angle_))) ; + +} + +bool Cone::operator != ( const Cone& aCone ) const +{ + return !((*this) == aCone) ; +} + +bool Cone::isDefined ( ) const +{ + return apex_.isDefined() && axis_.isDefined() && angle_.isDefined() ; +} + +bool Cone::intersects ( const Sphere& aSphere, + const Size aDiscretizationLevel ) const +{ + + if (!aSphere.isDefined()) + { + throw library::core::error::runtime::Undefined("Sphere") ; + } + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + for (const auto& ray : this->getRaysOfLateralSurface(aDiscretizationLevel)) // [TBM] Could be improved by calculating rays on the fly + { + + if (ray.intersects(aSphere)) + { + return true ; + } + + } + + return false ; + +} + +bool Cone::intersects ( const Ellipsoid& anEllipsoid, + const Size aDiscretizationLevel ) const +{ + + if (!anEllipsoid.isDefined()) + { + throw library::core::error::runtime::Undefined("Ellipsoid") ; + } + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + for (const auto& ray : this->getRaysOfLateralSurface(aDiscretizationLevel)) // [TBM] Could be improved by calculating rays on the fly + { + + if (ray.intersects(anEllipsoid)) + { + return true ; + } + + } + + return false ; + +} + +Point Cone::getApex ( ) const +{ + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + return apex_ ; + +} + +Vector3d Cone::getAxis ( ) const +{ + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + return axis_ ; + +} + +Angle Cone::getAngle ( ) const +{ + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + return angle_ ; + +} + +Array Cone::getRaysOfLateralSurface ( const Size aRayCount ) const +{ + + using library::math::obj::Interval ; + using library::math::geom::d3::trf::rot::Quaternion ; + using library::math::geom::d3::trf::rot::RotationVector ; + + if (aRayCount == 0) + { + throw library::core::error::runtime::Wrong("Ray count") ; + } + + const Vector3d referenceDirection = (std::abs(axis_.dot(Vector3d::X())) < 0.5) ? axis_.cross(Vector3d::X()).normalized() : axis_.cross(Vector3d::Y()).normalized() ; + + const Ray referenceRay = { apex_, Quaternion::RotationVector(RotationVector(referenceDirection, angle_)).toConjugate() * axis_ } ; + + const Array angles_rad = (aRayCount > 1) ? Interval::HalfOpenRight(0.0, 360.0).generateArrayWithSize(aRayCount) : Array { 0.0 } ; + + Array rays = Array::Empty() ; + + rays.reserve(angles_rad.getSize()) ; + + for (const auto& angle_rad : angles_rad) + { + + const Angle angle = Angle::Degrees(angle_rad) ; + + const Ray ray = { apex_, Quaternion::RotationVector(RotationVector(axis_, angle)).toConjugate() * referenceRay.getDirection() } ; + + rays.add(ray) ; + + } + + return rays ; + +} + +Intersection Cone::intersectionWith ( const Sphere& aSphere, + const bool onlyInSight, + const Size aDiscretizationLevel ) const +{ + + if (!aSphere.isDefined()) + { + throw library::core::error::runtime::Undefined("Sphere") ; + } + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + Array firstIntersectionPoints = Array::Empty() ; + Array secondIntersectionPoints = Array::Empty() ; + + for (const auto& ray : this->getRaysOfLateralSurface(aDiscretizationLevel)) + { + + const Intersection intersection = ray.intersectionWith(aSphere, onlyInSight) ; + + if (!intersection.isEmpty()) + { + + if (intersection.accessComposite().is()) + { + firstIntersectionPoints.add(intersection.accessComposite().as()) ; + } + else if (intersection.accessComposite().is()) + { + + const PointSet& pointSet = intersection.accessComposite().as() ; + + bool secondIntersectionPointAdded = false ; + + for (const auto& point : pointSet) + { + + if (!secondIntersectionPointAdded) + { + + secondIntersectionPoints.add(point) ; + + secondIntersectionPointAdded = true ; + + } + else + { + firstIntersectionPoints.add(point) ; + } + + } + + } + + } + + } + + if ((!firstIntersectionPoints.isEmpty()) && (!secondIntersectionPoints.isEmpty()) && (!onlyInSight)) + { + return Intersection::LineString(LineString(firstIntersectionPoints)) + Intersection::LineString(LineString(secondIntersectionPoints)) ; + } + else if (!firstIntersectionPoints.isEmpty()) + { + return Intersection::LineString(LineString(firstIntersectionPoints)) ; + } + else if (!secondIntersectionPoints.isEmpty()) + { + return Intersection::LineString(LineString(secondIntersectionPoints)) ; + } + + return Intersection::Empty() ; + +} + +Intersection Cone::intersectionWith ( const Ellipsoid& anEllipsoid, + const bool onlyInSight, + const Size aDiscretizationLevel ) const +{ + + if (!anEllipsoid.isDefined()) + { + throw library::core::error::runtime::Undefined("Ellipsoid") ; + } + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + Array firstIntersectionPoints = Array::Empty() ; + Array secondIntersectionPoints = Array::Empty() ; + + for (const auto& ray : this->getRaysOfLateralSurface(aDiscretizationLevel)) + { + + const Intersection intersection = ray.intersectionWith(anEllipsoid, onlyInSight) ; + + if (!intersection.isEmpty()) + { + + if (intersection.accessComposite().is()) + { + firstIntersectionPoints.add(intersection.accessComposite().as()) ; + } + else if (intersection.accessComposite().is()) + { + + const PointSet& pointSet = intersection.accessComposite().as() ; + + const Point closestPointToApex = pointSet.getPointClosestTo(apex_) ; + + firstIntersectionPoints.add(closestPointToApex) ; + + for (const auto& point : pointSet) + { + + if (point != closestPointToApex) + { + + secondIntersectionPoints.add(point) ; + + break ; + + } + + } + + } + + } + + } + + if ((!firstIntersectionPoints.isEmpty()) && (!secondIntersectionPoints.isEmpty()) && (!onlyInSight)) + { + return Intersection::LineString(LineString(firstIntersectionPoints)) + Intersection::LineString(LineString(secondIntersectionPoints)) ; + } + else if (!firstIntersectionPoints.isEmpty()) + { + return Intersection::LineString(LineString(firstIntersectionPoints)) ; + } + else if (!secondIntersectionPoints.isEmpty()) + { + return Intersection::LineString(LineString(secondIntersectionPoints)) ; + } + + return Intersection::Empty() ; + +} + +void Cone::print ( std::ostream& anOutputStream, + bool displayDecorators ) const +{ + + displayDecorators ? library::core::utils::Print::Header(anOutputStream, "Cone") : void () ; + + library::core::utils::Print::Line(anOutputStream) << "Apex:" << (apex_.isDefined() ? apex_.toString() : "Undefined") ; + library::core::utils::Print::Line(anOutputStream) << "Axis:" << (axis_.isDefined() ? axis_.toString() : "Undefined") ; + library::core::utils::Print::Line(anOutputStream) << "Angle:" << (angle_.isDefined() ? angle_.toString() : "Undefined") ; + + displayDecorators ? library::core::utils::Print::Footer(anOutputStream) : void () ; + +} + +void Cone::applyTransformation ( const Transformation& aTransformation ) +{ + + if (!aTransformation.isDefined()) + { + throw library::core::error::runtime::Undefined("Transformation") ; + } + + if (!this->isDefined()) + { + throw library::core::error::runtime::Undefined("Cone") ; + } + + apex_ = aTransformation.applyTo(apex_) ; + axis_ = aTransformation.applyTo(axis_) ; + + axis_.normalize() ; + +} + +Cone Cone::Undefined ( ) +{ + return { Point::Undefined(), Vector3d::Undefined(), Angle::Undefined() } ; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +} +} +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/src/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.cpp b/src/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.cpp index 857d6f03..0d1bdf36 100644 --- a/src/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.cpp +++ b/src/Library/Mathematics/Geometry/3D/Objects/Ellipsoid.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -448,6 +449,11 @@ bool Ellipsoid::intersects ( return aPyramid.intersects(*this) ; } +bool Ellipsoid::intersects ( const Cone& aCone ) const +{ + return aCone.intersects(*this) ; +} + bool Ellipsoid::contains ( const Point& aPoint ) const { @@ -896,6 +902,12 @@ Intersection Ellipsoid::intersectionWith ( return aPyramid.intersectionWith(*this, onlyInSight) ; } +Intersection Ellipsoid::intersectionWith ( const Cone& aCone, + const bool onlyInSight ) const +{ + return aCone.intersectionWith(*this, onlyInSight) ; +} + void Ellipsoid::print ( std::ostream& anOutputStream, bool displayDecorators ) const { diff --git a/src/Library/Mathematics/Geometry/3D/Objects/Pyramid.cpp b/src/Library/Mathematics/Geometry/3D/Objects/Pyramid.cpp index bbcfcb40..8f236226 100644 --- a/src/Library/Mathematics/Geometry/3D/Objects/Pyramid.cpp +++ b/src/Library/Mathematics/Geometry/3D/Objects/Pyramid.cpp @@ -223,23 +223,32 @@ Array Pyramid::getRaysOfLateralFaceAt ( using library::math::geom::d3::trf::rot::Quaternion ; using library::math::geom::d3::trf::rot::RotationVector ; - if (aRayCount < 2) - { - throw library::core::error::runtime::Wrong("Ray count") ; - } + // if (aRayCount < 2) + // { + // throw library::core::error::RuntimeError("Ray count [{}] lower than 2.", aRayCount) ; + // } const Segment baseEdge = base_.getEdgeAt(aLateralFaceIndex) ; const Vector3d firstRayDirection = (baseEdge.getFirstPoint() - apex_).normalized() ; const Vector3d secondRayDirection = (baseEdge.getSecondPoint() - apex_).normalized() ; + if (firstRayDirection == secondRayDirection) + { + return { { apex_, firstRayDirection } } ; + } + const Vector3d rotationAxis = firstRayDirection.cross(secondRayDirection).normalized() ; const Angle angleBetweenRays = Angle::Between(firstRayDirection, secondRayDirection) ; + const Array angles_rad = (aRayCount > 1) ? Interval::Closed(0.0, angleBetweenRays.inRadians()).generateArrayWithSize(aRayCount) : Array { 0.0 } ; + Array rays = Array::Empty() ; - for (const auto& angle_rad : Interval::Closed(0.0, angleBetweenRays.inRadians()).generateArrayWithSize(aRayCount)) + rays.reserve(angles_rad.getSize()) ; + + for (const auto& angle_rad : angles_rad) { const Ray ray = { apex_, Quaternion::RotationVector(RotationVector(rotationAxis, Angle::Radians(angle_rad))).conjugate() * firstRayDirection } ; @@ -257,7 +266,7 @@ Array Pyramid::getRaysOfLateralFaces ( if (aRayCount < this->getLateralFaceCount()) { - throw library::core::error::runtime::Wrong("Ray count") ; + throw library::core::error::RuntimeError("Ray count [{}] lower than lateral face count [{}].", aRayCount, this->getLateralFaceCount()) ; } Size lateralRayCount = aRayCount / this->getLateralFaceCount() ; @@ -392,26 +401,46 @@ Intersection Pyramid::intersectionWith ( const PointSet& pointSet = intersection.accessComposite().as() ; - bool secondIntersectionPointAdded = false ; + const Point closestPointToApex = pointSet.getPointClosestTo(apex_) ; + + firstIntersectionPoints.add(closestPointToApex) ; for (const auto& point : pointSet) { - if (!secondIntersectionPointAdded) + if (point != closestPointToApex) { - + secondIntersectionPoints.add(point) ; - secondIntersectionPointAdded = true ; + break ; } - else - { - firstIntersectionPoints.add(point) ; - } } + // firstIntersectionPoints.add(pointSet.getPointClosestTo(apex_)) ; + + // bool secondIntersectionPointAdded = false ; + + // for (const auto& point : pointSet) + // { + + // if (!secondIntersectionPointAdded) + // { + + // secondIntersectionPoints.add(point) ; + + // secondIntersectionPointAdded = true ; + + // } + // else + // { + // firstIntersectionPoints.add(point) ; + // } + + // } + } } diff --git a/src/Library/Mathematics/Geometry/3D/Objects/Sphere.cpp b/src/Library/Mathematics/Geometry/3D/Objects/Sphere.cpp index 5f08d0e5..80874457 100644 --- a/src/Library/Mathematics/Geometry/3D/Objects/Sphere.cpp +++ b/src/Library/Mathematics/Geometry/3D/Objects/Sphere.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -272,6 +273,11 @@ bool Sphere::intersects ( return aPyramid.intersects(*this) ; } +bool Sphere::intersects ( const Cone& aCone ) const +{ + return aCone.intersects(*this) ; +} + bool Sphere::contains ( const Point& aPoint ) const { @@ -591,6 +597,12 @@ Intersection Sphere::intersectionWith ( return aPyramid.intersectionWith(*this, onlyInSight) ; } +Intersection Sphere::intersectionWith ( const Cone& aCone, + const bool onlyInSight ) const +{ + return aCone.intersectionWith(*this, onlyInSight) ; +} + void Sphere::print ( std::ostream& anOutputStream, bool displayDecorators ) const { diff --git a/src/Library/Mathematics/Geometry/3D/Transformation.cpp b/src/Library/Mathematics/Geometry/3D/Transformation.cpp index 6be59574..e2e6f0bb 100644 --- a/src/Library/Mathematics/Geometry/3D/Transformation.cpp +++ b/src/Library/Mathematics/Geometry/3D/Transformation.cpp @@ -273,7 +273,11 @@ void Transformation::print ( displayDecorators ? library::core::utils::Print::Header(anOutputStream, "3D :: Transformation") : void () ; - library::core::utils::Print::Line(anOutputStream) << "Type" << Transformation::StringFromType(type_) ; + library::core::utils::Print::Line(anOutputStream) << "Type:" << Transformation::StringFromType(type_) ; + + library::core::utils::Print::Line(anOutputStream) << "Matrix:" ; + + anOutputStream << matrix_ << std::endl ; displayDecorators ? library::core::utils::Print::Footer(anOutputStream) : void () ; @@ -311,8 +315,6 @@ Transformation Transformation::Translation ( Transformation Transformation::Rotation ( const RotationVector& aRotationVector ) { - using library::math::geom::d3::trf::rot::RotationMatrix ; - if (!aRotationVector.isDefined()) { throw library::core::error::runtime::Undefined("Rotation vector") ; @@ -326,6 +328,22 @@ Transformation Transformation::Rotation ( } +Transformation Transformation::Rotation ( const RotationMatrix& aRotationMatrix ) +{ + + if (!aRotationMatrix.isDefined()) + { + throw library::core::error::runtime::Undefined("Rotation matrix") ; + } + + Matrix4d transformationMatrix = Matrix4d::Identity() ; + + transformationMatrix.block<3, 3>(0, 0) = aRotationMatrix.getMatrix().transpose() ; + + return { Transformation::Type::Rotation, transformationMatrix, true } ; + +} + Transformation Transformation::RotationAround ( const Point& aPoint, const RotationVector& aRotationVector ) { diff --git a/src/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.cpp b/src/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.cpp index d9f08f98..9d34ca31 100644 --- a/src/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.cpp +++ b/src/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.cpp @@ -126,12 +126,48 @@ String RotationVector::toString ( RotationVector RotationVector::Undefined ( ) { - return RotationVector() ; + return {} ; } RotationVector RotationVector::Unit ( ) { - return RotationVector({ 0.0, 0.0, 1.0 }, Angle::Zero()) ; + return { Vector3d::Z(), Angle::Zero() } ; +} + +RotationVector RotationVector::X ( const Angle& anAngle ) +{ + + if (!anAngle.isDefined()) + { + throw library::core::error::runtime::Undefined("Angle") ; + } + + return { Vector3d::X(), anAngle } ; + +} + +RotationVector RotationVector::Y ( const Angle& anAngle ) +{ + + if (!anAngle.isDefined()) + { + throw library::core::error::runtime::Undefined("Angle") ; + } + + return { Vector3d::Y(), anAngle } ; + +} + +RotationVector RotationVector::Z ( const Angle& anAngle ) +{ + + if (!anAngle.isDefined()) + { + throw library::core::error::runtime::Undefined("Angle") ; + } + + return { Vector3d::Z(), anAngle } ; + } RotationVector RotationVector::Quaternion ( const rot::Quaternion& aQuaternion ) diff --git a/src/Library/Mathematics/Objects/Interval.tpp b/src/Library/Mathematics/Objects/Interval.tpp index 48457e1b..3f561ec8 100644 --- a/src/Library/Mathematics/Objects/Interval.tpp +++ b/src/Library/Mathematics/Objects/Interval.tpp @@ -324,14 +324,43 @@ ctnr::Array Interval::generateArrayWithSize ( throw library::core::error::runtime::Wrong("Array size") ; } - const T step = (this->accessUpperBound() - this->accessLowerBound()) / static_cast(anArraySize - 1) ; + T step = T::Undefined() ; + T value = T::Undefined() ; + + switch (type_) + { + + case Interval::Type::Closed: + step = (this->accessUpperBound() - this->accessLowerBound()) / static_cast(anArraySize - 1) ; + value = this->accessLowerBound() ; + break ; + + case Interval::Type::Open: + step = (this->accessUpperBound() - this->accessLowerBound()) / static_cast(anArraySize + 1) ; + value = this->accessLowerBound() + step ; + break ; + + case Interval::Type::HalfOpenLeft: + step = (this->accessUpperBound() - this->accessLowerBound()) / static_cast(anArraySize) ; + value = this->accessLowerBound() + step ; + break ; + + case Interval::Type::HalfOpenRight: + step = (this->accessUpperBound() - this->accessLowerBound()) / static_cast(anArraySize) ; + value = this->accessLowerBound() ; + break ; + + default: + throw library::core::error::runtime::Wrong("Type") ; + break ; + + } ctnr::Array array(anArraySize, T::Undefined()) ; - T value = T::Undefined() ; typename ctnr::Array::Iterator arrayIt ; - for (arrayIt = array.begin(), value = this->accessLowerBound(); arrayIt != array.end(); ++arrayIt, value += step) + for (arrayIt = array.begin(); arrayIt != array.end(); ++arrayIt, value += step) { *arrayIt = value ; } diff --git a/test/Library/Mathematics/Geometry/2D/Transformation.test.cpp b/test/Library/Mathematics/Geometry/2D/Transformation.test.cpp index 00c7a5e8..d38def40 100644 --- a/test/Library/Mathematics/Geometry/2D/Transformation.test.cpp +++ b/test/Library/Mathematics/Geometry/2D/Transformation.test.cpp @@ -7,8 +7,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include #include +#include +#include +#include #include @@ -209,18 +211,95 @@ // } -// TEST (Library_Mathematics_Geometry_2D_Transformation, RotationAround) -// { +TEST (Library_Mathematics_Geometry_2D_Transformation, RotationAround) +{ + + using library::core::types::String ; -// using library::math::geom::d2::Transformation ; + using library::math::geom::Angle ; + using library::math::geom::d2::objects::Point ; + using library::math::geom::d2::Transformation ; -// { + { -// FAIL() ; + const Point rotationCenter = { 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; -// } + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationAngle) ; -// } + Point point = { 0.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { 0.0, 0.0 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 1.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; + + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationAngle) ; + + Point point = { 1.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { 1.0, 0.0 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; + + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationAngle) ; + + Point point = { 1.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { +0.70710678118, +0.70710678118 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(-45.0) ; + + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationAngle) ; + + Point point = { 1.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { +0.70710678118, -0.70710678118 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; + + EXPECT_ANY_THROW(Transformation::RotationAround(Point::Undefined(), rotationAngle)) ; + EXPECT_ANY_THROW(Transformation::RotationAround(rotationCenter, Angle::Undefined())) ; + EXPECT_ANY_THROW(Transformation::RotationAround(Point::Undefined(), Angle::Undefined())) ; + + } + +} // TEST (Library_Mathematics_Geometry_2D_Transformation, StringFromType) // { diff --git a/test/Library/Mathematics/Geometry/3D/Objects/Cone.test.cpp b/test/Library/Mathematics/Geometry/3D/Objects/Cone.test.cpp new file mode 100644 index 00000000..597ec3ab --- /dev/null +++ b/test/Library/Mathematics/Geometry/3D/Objects/Cone.test.cpp @@ -0,0 +1,507 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/// @project Library/Mathematics +/// @file Library/Mathematics/Geometry/3D/Objects/Cone.test.cpp +/// @author Lucas Brémond +/// @license TBD + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, Constructor) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_NO_THROW(Cone(apex, axis, angle)) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, Clone) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_NO_THROW(Cone(apex, axis, angle).clone()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, EqualToOperator) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_TRUE(Cone(apex, axis, angle) == Cone(apex, axis, angle)) ; + + } + + { + + const Point firstApex = { 0.0, 0.0, 0.0 } ; + const Vector3d firstAxis = { +1.0, 0.0, 0.0 } ; + const Angle firstAngle = Angle::Degrees(135.0) ; + + const Cone firstCone = { firstApex, firstAxis, firstAngle } ; + + const Point secondApex = { 0.0, 0.0, 0.0 } ; + const Vector3d secondXis = { -1.0, 0.0, 0.0 } ; + const Angle secondAngle = Angle::Degrees(45.0) ; + + const Cone secondCone = { secondApex, secondXis, secondAngle } ; + + EXPECT_TRUE(firstCone == secondCone) ; + + } + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_FALSE(Cone(apex, axis, angle) == Cone::Undefined()) ; + EXPECT_FALSE(Cone::Undefined() == Cone(apex, axis, angle)) ; + EXPECT_FALSE(Cone::Undefined() == Cone::Undefined()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, NotEqualToOperator) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_FALSE(Cone(apex, axis, angle) != Cone(apex, axis, angle)) ; + + } + + { + + const Point firstApex = { 0.0, 0.0, 0.0 } ; + const Vector3d firstAxis = { +1.0, 0.0, 0.0 } ; + const Angle firstAngle = Angle::Degrees(135.0) ; + + const Cone firstCone = { firstApex, firstAxis, firstAngle } ; + + const Point secondApex = { 0.0, 0.0, 0.0 } ; + const Vector3d secondXis = { -1.0, 0.0, 0.0 } ; + const Angle secondAngle = Angle::Degrees(45.0) ; + + const Cone secondCone = { secondApex, secondXis, secondAngle } ; + + EXPECT_FALSE(firstCone != secondCone) ; + + } + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_TRUE(Cone(apex, axis, angle) != Cone::Undefined()) ; + EXPECT_TRUE(Cone::Undefined() != Cone(apex, axis, angle)) ; + EXPECT_TRUE(Cone::Undefined() != Cone::Undefined()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, StreamOperator) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + testing::internal::CaptureStdout() ; + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_NO_THROW(std::cout << Cone(apex, axis, angle) << std::endl) ; + + EXPECT_FALSE(testing::internal::GetCapturedStdout().empty()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, IsDefined) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_TRUE(Cone(apex, axis, angle).isDefined()) ; + + } + + { + + EXPECT_FALSE(Cone::Undefined().isDefined()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, Intersects_Ellipsoid) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Ellipsoid ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { -10.0, 0.0, 10.0 } ; + const Vector3d axis = Vector3d::X() ; + const Angle angle = Angle::Degrees(10.0) ; + + const Cone cone = { apex, axis, angle } ; + + const Ellipsoid ellipsoid = { { 0.0, 0.0, 10.0 }, 5.0, 5.0, 5.0 } ; + + EXPECT_TRUE(cone.intersects(ellipsoid)) ; + + } + + { + + EXPECT_ANY_THROW(Cone::Undefined().intersects(Ellipsoid::Undefined())) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, GetApex) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_EQ(apex, Cone(apex, axis, angle).getApex()) ; + + } + + { + + EXPECT_ANY_THROW(Cone::Undefined().getApex()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, GetAxis) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_EQ(axis, Cone(apex, axis, angle).getAxis()) ; + + } + + { + + EXPECT_ANY_THROW(Cone::Undefined().getAxis()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, GetAngle) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_EQ(angle, Cone(apex, axis, angle).getAngle()) ; + + } + + { + + EXPECT_ANY_THROW(Cone::Undefined().getAngle()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, GetRaysOfLateralSurface) +{ + + using library::core::types::Real ; + using library::core::ctnr::Array ; + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Ray ; + using library::math::geom::d3::objects::Cone ; + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + const Array rays = Cone(apex, axis, angle).getRaysOfLateralSurface(4) ; + + const Array referenceRays = + { + { apex, { 0.707106781186548, 0.0, 0.707106781186547 } }, + { apex, { 1.11022302462516e-16, 0.707106781186548, 0.707106781186547 } }, + { apex, { -0.707106781186548, 8.65956056235493e-17, 0.707106781186547 } }, + { apex, { -1.11022302462516e-16, -0.707106781186548, 0.707106781186547 } } + } ; + + EXPECT_TRUE + ( + rays.isNear + ( + referenceRays, + [] (const Ray& aFirstRay, const Ray& aSecondRay) -> bool + { + + return aFirstRay.getOrigin().isNear(aSecondRay.getOrigin(), Real::Epsilon()) + && aFirstRay.getDirection().isNear(aSecondRay.getDirection(), Real::Epsilon()) ; + + } + ) + ) ; + + } + + { + + EXPECT_ANY_THROW(Cone::Undefined().getRaysOfLateralSurface()) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, IntersectionWith_Ellipsoid) +{ + + using library::core::types::Real ; + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::LineString ; + using library::math::geom::d3::objects::Ellipsoid ; + using library::math::geom::d3::objects::Cone ; + using library::math::geom::d3::Intersection ; + + { + + const Point apex = { 10.0, 0.0, 10.0 } ; + const Vector3d axis = { -1.0, 0.0, 0.0 } ; + const Angle angle = Angle::Degrees(10.0) ; + + const Cone cone = { apex, axis, angle } ; + + const Ellipsoid ellipsoid = { { 0.0, 0.0, 10.0 }, 5.0, 5.0, 5.0 } ; + + const Intersection intersection = cone.intersectionWith(ellipsoid, true, 4) ; + + EXPECT_TRUE(intersection.isDefined()) ; + EXPECT_FALSE(intersection.isEmpty()) ; + EXPECT_TRUE(intersection.accessComposite().is()) ; + + const LineString intersectionLineString = intersection.accessComposite().as() ; + + EXPECT_EQ(4, intersectionLineString.getPointCount()) ; + + const LineString referenceLineString = + { + { + { 4.91908097261278, 0.895903111323379, 10.0 }, + { 4.91908097261278, 0.0, 9.10409688867662 }, + { 4.91908097261278, -0.895903111323379, 10.0 }, + { 4.91908097261278, 0.0, 10.8959031113234 }, + } + } ; + + EXPECT_TRUE(intersectionLineString.isNear(referenceLineString, 1e-10)) ; + + } + + { + + EXPECT_ANY_THROW(Cone::Undefined().intersectionWith(Ellipsoid::Undefined())) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, ApplyTransformation) +{ + + using library::core::types::Real ; + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::objects::Cone ; + using library::math::geom::d3::Transformation ; + using library::math::geom::d3::trf::rot::RotationVector ; + + // Translation + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + Cone cone = { apex, axis, angle } ; + + cone.applyTransformation(Transformation::Translation({ 4.0, 5.0, 6.0 })) ; + + EXPECT_EQ(Cone({ 4.0, 5.0, 6.0 }, axis, angle), cone) ; + + } + + // Rotation + + { + + const Point apex = { 0.0, 1.0, 0.0 } ; + const Vector3d axis = { 0.0, 1.0, 0.0 } ; + const Angle angle = Angle::Degrees(45.0) ; + + Cone cone = { apex, axis, angle } ; + + cone.applyTransformation(Transformation::Rotation(RotationVector({ 1.0, 0.0, 0.0 }, Angle::Degrees(90.0)))) ; + + const Point referenceApex = { 0.0, 0.0, 1.0 } ; + const Vector3d referenceAxis = { 0.0, 0.0, 1.0 } ; + const Angle referenceAngle = Angle::Degrees(45.0) ; + + const Cone referenceCone = { referenceApex, referenceAxis, referenceAngle } ; + + EXPECT_TRUE(cone.getApex().isNear(referenceCone.getApex(), Real::Epsilon())) << referenceCone.getApex().toString() << cone.getApex().toString() ; + EXPECT_TRUE(cone.getAxis().isNear(referenceCone.getAxis(), Real::Epsilon())) << referenceCone.getAxis().toString() << cone.getAxis().toString() ; + EXPECT_TRUE(cone.getAngle().inDegrees().isNear(referenceCone.getAngle().inDegrees(), Real::Epsilon())) << referenceCone.getAngle().toString() << cone.getAngle().toString() ; + + } + + { + + const Point apex = { 0.0, 0.0, 0.0 } ; + const Vector3d axis = Vector3d::Z() ; + const Angle angle = Angle::Degrees(45.0) ; + + EXPECT_ANY_THROW(Cone::Undefined().applyTransformation(Transformation::Undefined())) ; + EXPECT_ANY_THROW(Cone::Undefined().applyTransformation(Transformation::Identity())) ; + EXPECT_ANY_THROW(Cone(apex, axis, angle).applyTransformation(Transformation::Undefined())) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Objects_Cone, Undefined) +{ + + using library::math::geom::d3::objects::Cone ; + + { + + EXPECT_NO_THROW(Cone::Undefined()) ; + EXPECT_FALSE(Cone::Undefined().isDefined()) ; + + } + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/test/Library/Mathematics/Geometry/3D/Transformation.test.cpp b/test/Library/Mathematics/Geometry/3D/Transformation.test.cpp index bd2f0df7..d589197b 100644 --- a/test/Library/Mathematics/Geometry/3D/Transformation.test.cpp +++ b/test/Library/Mathematics/Geometry/3D/Transformation.test.cpp @@ -7,8 +7,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include +#include #include +#include +#include #include @@ -222,18 +224,101 @@ // } -// TEST (Library_Mathematics_Geometry_3D_Transformation, RotationAround) -// { +TEST (Library_Mathematics_Geometry_3D_Transformation, RotationAround) +{ -// using library::math::geom::d3::Transformation ; + using library::core::types::String ; + + using library::math::geom::Angle ; + using library::math::geom::d3::objects::Point ; + using library::math::geom::d3::Transformation ; + using library::math::geom::d3::trf::rot::RotationVector ; -// { + { -// FAIL() ; + const Point rotationCenter = { 0.0, 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; + const RotationVector rotationVector = { { 0.0, 0.0, 1.0 }, rotationAngle } ; -// } + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationVector) ; -// } + Point point = { 0.0, 0.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { 0.0, 0.0, 0.0 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 1.0, 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; + const RotationVector rotationVector = { { 0.0, 0.0, 1.0 }, rotationAngle } ; + + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationVector) ; + + Point point = { 1.0, 0.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { 1.0, 0.0, 0.0 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 0.0, 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; + const RotationVector rotationVector = { { 0.0, 0.0, 1.0 }, rotationAngle } ; + + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationVector) ; + + Point point = { 1.0, 0.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { +0.70710678118, +0.70710678118, 0.0 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 0.0, 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(-45.0) ; + const RotationVector rotationVector = { { 0.0, 0.0, 1.0 }, rotationAngle } ; + + const Transformation transformation = Transformation::RotationAround(rotationCenter, rotationVector) ; + + Point point = { 1.0, 0.0, 0.0 } ; + + point.applyTransformation(transformation) ; + + const Point rotatedPoint_ref = { +0.70710678118, -0.70710678118, 0.0 } ; + + EXPECT_TRUE(point.isNear(rotatedPoint_ref, 1e-11)) << String::Format("{} ~ {}", point.toString(), rotatedPoint_ref.toString()) ; + + } + + { + + const Point rotationCenter = { 0.0, 0.0, 0.0 } ; + const Angle rotationAngle = Angle::Degrees(45.0) ; + const RotationVector rotationVector = { { 0.0, 0.0, 1.0 }, rotationAngle } ; + + EXPECT_ANY_THROW(Transformation::RotationAround(Point::Undefined(), rotationVector)) ; + EXPECT_ANY_THROW(Transformation::RotationAround(rotationCenter, RotationVector::Undefined())) ; + EXPECT_ANY_THROW(Transformation::RotationAround(Point::Undefined(), RotationVector::Undefined())) ; + + } + +} // TEST (Library_Mathematics_Geometry_3D_Transformation, StringFromType) // { diff --git a/test/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.test.cpp b/test/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.test.cpp index f5193865..c4669e2c 100644 --- a/test/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.test.cpp +++ b/test/Library/Mathematics/Geometry/3D/Transformations/Rotations/RotationVector.test.cpp @@ -282,6 +282,84 @@ TEST (Library_Mathematics_Geometry_3D_Transformations_Rotations_RotationVector, } +TEST (Library_Mathematics_Geometry_3D_Transformations_Rotations_RotationVector, X) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::trf::rot::RotationVector ; + + { + + EXPECT_NO_THROW(RotationVector::X(Angle::Degrees(45.0))) ; + + const RotationVector rotationVector = RotationVector::X(Angle::Degrees(45.0)) ; + + EXPECT_EQ(Vector3d::X(), rotationVector.getAxis()) ; + EXPECT_EQ(Angle::Degrees(45.0), rotationVector.getAngle()) ; + + } + + { + + EXPECT_ANY_THROW(RotationVector::X(Angle::Undefined())) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Transformations_Rotations_RotationVector, Y) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::trf::rot::RotationVector ; + + { + + EXPECT_NO_THROW(RotationVector::Y(Angle::Degrees(45.0))) ; + + const RotationVector rotationVector = RotationVector::Y(Angle::Degrees(45.0)) ; + + EXPECT_EQ(Vector3d::Y(), rotationVector.getAxis()) ; + EXPECT_EQ(Angle::Degrees(45.0), rotationVector.getAngle()) ; + + } + + { + + EXPECT_ANY_THROW(RotationVector::Y(Angle::Undefined())) ; + + } + +} + +TEST (Library_Mathematics_Geometry_3D_Transformations_Rotations_RotationVector, Z) +{ + + using library::math::obj::Vector3d ; + using library::math::geom::Angle ; + using library::math::geom::d3::trf::rot::RotationVector ; + + { + + EXPECT_NO_THROW(RotationVector::Z(Angle::Degrees(45.0))) ; + + const RotationVector rotationVector = RotationVector::Z(Angle::Degrees(45.0)) ; + + EXPECT_EQ(Vector3d::Z(), rotationVector.getAxis()) ; + EXPECT_EQ(Angle::Degrees(45.0), rotationVector.getAngle()) ; + + } + + { + + EXPECT_ANY_THROW(RotationVector::Z(Angle::Undefined())) ; + + } + +} + TEST (Library_Mathematics_Geometry_3D_Transformations_Rotations_RotationVector, Quaternion) { diff --git a/test/Library/Mathematics/Objects/Interval.test.cpp b/test/Library/Mathematics/Objects/Interval.test.cpp index 40852917..25cb078c 100644 --- a/test/Library/Mathematics/Objects/Interval.test.cpp +++ b/test/Library/Mathematics/Objects/Interval.test.cpp @@ -846,13 +846,15 @@ TEST (Library_Mathematics_Objects_Interval, GenerateArrayWithSize) using library::math::obj::Interval ; + // Closed + { const Interval interval = { 0.0, 1.0, Interval::Type::Closed } ; const Array array = interval.generateArrayWithSize(3) ; - EXPECT_EQ(Array({ 0.0, 0.5, 1.0 }), array) ; + EXPECT_TRUE(array.isNear(Array({ 0.0, 0.5, 1.0 }), Real::Epsilon())) ; } @@ -862,7 +864,7 @@ TEST (Library_Mathematics_Objects_Interval, GenerateArrayWithSize) const Array array = interval.generateArrayWithSize(5) ; - EXPECT_EQ(Array({ 0.0, 0.25, 0.5, 0.75, 1.0 }), array) ; + EXPECT_TRUE(array.isNear(Array({ 0.0, 0.25, 0.5, 0.75, 1.0 }), Real::Epsilon())) ; } @@ -872,7 +874,73 @@ TEST (Library_Mathematics_Objects_Interval, GenerateArrayWithSize) const Array array = interval.generateArrayWithSize(2) ; - EXPECT_EQ(Array({ 0.0, 1.0 }), array) ; + EXPECT_TRUE(array.isNear(Array({ 0.0, 1.0 }), Real::Epsilon())) ; + + } + + // Open + + { + + const Interval interval = { 0.0, 1.0, Interval::Type::Open } ; + + const Array array = interval.generateArrayWithSize(3) ; + + EXPECT_TRUE(array.isNear(Array({ 0.25, 0.5, 0.75 }), Real::Epsilon())) ; + + } + + { + + const Interval interval = { 0.0, 1.0, Interval::Type::Open } ; + + const Array array = interval.generateArrayWithSize(4) ; + + EXPECT_TRUE(array.isNear(Array({ 0.2, 0.4, 0.6, 0.8 }), Real::Epsilon())) ; + + } + + // Half-Open Left + + { + + const Interval interval = { 0.0, 1.0, Interval::Type::HalfOpenLeft } ; + + const Array array = interval.generateArrayWithSize(4) ; + + EXPECT_TRUE(array.isNear(Array({ 0.25, 0.5, 0.75, 1.0 }), Real::Epsilon())) ; + + } + + { + + const Interval interval = { 0.0, 1.0, Interval::Type::HalfOpenLeft } ; + + const Array array = interval.generateArrayWithSize(5) ; + + EXPECT_TRUE(array.isNear(Array({ 0.2, 0.4, 0.6, 0.8, 1.0 }), Real::Epsilon())) ; + + } + + // Half-Open Right + + { + + const Interval interval = { 0.0, 1.0, Interval::Type::HalfOpenRight } ; + + const Array array = interval.generateArrayWithSize(4) ; + + EXPECT_TRUE(array.isNear(Array({ 0.0, 0.25, 0.5, 0.75 }), Real::Epsilon())) ; + + } + + { + + const Interval interval = { 0.0, 1.0, Interval::Type::HalfOpenRight } ; + + const Array array = interval.generateArrayWithSize(5) ; + + EXPECT_TRUE(array.isNear(Array({ 0.0, 0.2, 0.4, 0.6, 0.8 }), Real::Epsilon())) ; } diff --git a/tools/.env b/tools/.env index b128d8a2..ff2bc863 100644 --- a/tools/.env +++ b/tools/.env @@ -38,7 +38,7 @@ fi repository_name="openspacecollective" # image_version="$(echo ${version} | head -c 5)" -image_version="0.1.11" +image_version="0.1.12" image_name="${repository_name}/${project_name}:${image_version}" diff --git a/tools/development/docker/Dockerfile b/tools/development/docker/Dockerfile index ef4a3db9..61d09105 100644 --- a/tools/development/docker/Dockerfile +++ b/tools/development/docker/Dockerfile @@ -57,12 +57,12 @@ RUN mkdir /tmp/geometric-tools-engine \ && rm -rf /tmp/geometric-tools-engine \ && popd > /dev/null -## Library ▸ Core [0.1.15] +## Library ▸ Core [0.1.16] RUN mkdir -p /tmp/library-core \ && pushd /tmp/library-core > /dev/null \ - && wget --quiet https://github.com/open-space-collective/library-core/releases/download/0.1.15/library-core-0.1.15-1.x86_64-runtime.rpm \ - && wget --quiet https://github.com/open-space-collective/library-core/releases/download/0.1.15/library-core-0.1.15-1.x86_64-devel.rpm \ + && wget --quiet https://github.com/open-space-collective/library-core/releases/download/0.1.16/library-core-0.1.16-1.x86_64-runtime.rpm \ + && wget --quiet https://github.com/open-space-collective/library-core/releases/download/0.1.16/library-core-0.1.16-1.x86_64-devel.rpm \ && dnf install -y ./*.rpm \ && rm -rf /tmp/library-core \ && popd > /dev/null diff --git a/tools/development/helpers/build.sh b/tools/development/helpers/build.sh index 73874ac1..24863b17 100755 --- a/tools/development/helpers/build.sh +++ b/tools/development/helpers/build.sh @@ -9,8 +9,16 @@ ################################################################################################################################################################ -cmake .. +if [[ ! -z $1 ]] && [[ $1 == "--debug" ]]; then -make -j ${cpu_count} + cmake -DCMAKE_BUILD_TYPE=Debug .. + +else + + cmake .. + +fi + +make -j ${cpu_count:-1} ################################################################################################################################################################ \ No newline at end of file