From 9023098090d16ea8131d1f1bd179169a2b72d2b3 Mon Sep 17 00:00:00 2001 From: Veniamin Viflyantsev Date: Tue, 17 Aug 2021 13:59:59 +0300 Subject: [PATCH 1/4] implementation of geometry projections of vectors to a line/plane --- .../kmath/geometry/Euclidean2DSpace.kt | 8 +- .../kmath/geometry/Euclidean3DSpace.kt | 8 +- .../kscience/kmath/geometry/Projections.kt | 20 +++++ .../kmath/geometry/Euclidean2DSpaceTest.kt | 62 ++++++++++++++ .../kmath/geometry/Euclidean3DSpaceTest.kt | 74 +++++++++++++++++ .../kmath/geometry/ProjectionAlongTest.kt | 60 ++++++++++++++ .../kmath/geometry/ProjectionOntoLineTest.kt | 82 +++++++++++++++++++ .../kscience/kmath/geometry/Vector2DTest.kt | 36 ++++++++ .../kscience/kmath/geometry/Vector3DTest.kt | 41 ++++++++++ .../kscience/kmath/geometry/testUtils.kt | 41 ++++++++++ 10 files changed, 424 insertions(+), 8 deletions(-) create mode 100644 kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt create mode 100644 kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt create mode 100644 kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt create mode 100644 kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt create mode 100644 kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt create mode 100644 kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt create mode 100644 kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt create mode 100644 kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt index 252e2fcd5..e8b1ce95b 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt @@ -12,14 +12,14 @@ import space.kscience.kmath.operations.invoke import kotlin.math.sqrt @OptIn(UnstableKMathAPI::class) -public interface Vector2D : Point, Vector{ +public interface Vector2D : Point, Vector { public val x: Double public val y: Double override val size: Int get() = 2 override operator fun get(index: Int): Double = when (index) { - 1 -> x - 2 -> y + 0 -> x + 1 -> y else -> error("Accessing outside of point bounds") } @@ -27,7 +27,7 @@ public interface Vector2D : Point, Vector{ } public val Vector2D.r: Double - get() = Euclidean2DSpace { sqrt(norm()) } + get() = Euclidean2DSpace { norm() } @Suppress("FunctionName") public fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt index b0b2d2079..d567bee9a 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt @@ -19,9 +19,9 @@ public interface Vector3D : Point, Vector { override val size: Int get() = 3 override operator fun get(index: Int): Double = when (index) { - 1 -> x - 2 -> y - 3 -> z + 0 -> x + 1 -> y + 2 -> z else -> error("Accessing outside of point bounds") } @@ -31,7 +31,7 @@ public interface Vector3D : Point, Vector { @Suppress("FunctionName") public fun Vector3D(x: Double, y: Double, z: Double): Vector3D = Vector3DImpl(x, y, z) -public val Vector3D.r: Double get() = Euclidean3DSpace { sqrt(norm()) } +public val Vector3D.r: Double get() = Euclidean3DSpace { norm() } private data class Vector3DImpl( override val x: Double, diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt new file mode 100644 index 000000000..d13ef03a1 --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt @@ -0,0 +1,20 @@ +package space.kscience.kmath.geometry + +/** + * Project vector to a line + * @param vector to project + * @param line line to which vector should be projected + */ +public fun GeometrySpace.projectToLine(vector: V, line: Line): V = with(line) { + base + (direction dot (vector - base)) / (direction dot direction) * direction +} + +/** + * Project vector to a hyper-plane, which is defined by a normal and base + * In 2d case it is projection to a line, in 3d case it is projection to a plane + * @param vector to project + * @param normal normal (perpendicular) vector to a hyper-plane to which vector should be projected + * @param base point belonging to a hyper-plane to which vector should be projected + */ +public fun GeometrySpace.projectAlong(vector: V, normal: V, base: V): V = + vector + normal * ((base - vector) dot normal) / (normal dot normal) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt new file mode 100644 index 000000000..6d5ae9948 --- /dev/null +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt @@ -0,0 +1,62 @@ +package space.kscience.kmath.geometry + +import kotlin.math.sqrt +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class Euclidean2DSpaceTest { + @Test + fun getZero() { + assertVectorEquals(Vector2D(0.0, 0.0), Euclidean2DSpace.zero) + } + + @Test + fun norm() { + with(Euclidean2DSpace) { + assertEquals(0.0, zero.norm()) + assertEquals(1.0, Vector2D(1.0, 0.0).norm()) + assertEquals(sqrt(2.0), Vector2D(1.0, 1.0).norm()) + assertEquals(sqrt(5.002001), Vector2D(-2.0, 1.001).norm()) + } + } + + @Test + fun dotProduct() { + with(Euclidean2DSpace) { + assertEquals(0.0, zero dot zero) + assertEquals(0.0, zero dot Vector2D(1.0, 0.0)) + assertEquals(0.0, Vector2D(-2.0, 0.001) dot zero) + assertEquals(0.0, Vector2D(1.0, 0.0) dot Vector2D(0.0, 1.0)) + + assertEquals(1.0, Vector2D(1.0, 0.0) dot Vector2D(1.0, 0.0)) + assertEquals(-2.0, Vector2D(0.0, 1.0) dot Vector2D(1.0, -2.0)) + assertEquals(2.0, Vector2D(1.0, 1.0) dot Vector2D(1.0, 1.0)) + assertEquals(4.001001, Vector2D(-2.0, 1.001) dot Vector2D(-2.0, 0.001)) + + assertEquals(-4.998, Vector2D(1.0, 2.0) dot Vector2D(-5.0, 0.001)) + } + } + + @Test + fun add() { + with(Euclidean2DSpace) { + assertVectorEquals( + Vector2D(-2.0, 0.001), + Vector2D(-2.0, 0.001) + zero + ) + assertVectorEquals( + Vector2D(-3.0, 3.001), + Vector2D(2.0, 3.0) + Vector2D(-5.0, 0.001) + ) + } + } + + @Test + fun multiply() { + with(Euclidean2DSpace) { + assertVectorEquals(Vector2D(-4.0, 0.0), Vector2D(-2.0, 0.0) * 2) + assertVectorEquals(Vector2D(4.0, 0.0), Vector2D(-2.0, 0.0) * -2) + assertVectorEquals(Vector2D(300.0, 0.0003), Vector2D(100.0, 0.0001) * 3) + } + } +} \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt new file mode 100644 index 000000000..9cce44c65 --- /dev/null +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt @@ -0,0 +1,74 @@ +package space.kscience.kmath.geometry + +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class Euclidean3DSpaceTest { + @Test + fun getZero() { + assertVectorEquals(Vector3D(0.0, 0.0, 0.0), Euclidean3DSpace.zero) + } + + @Test + fun distance() { + with(Euclidean3DSpace) { + assertEquals(0.0, zero.distanceTo(zero)) + assertEquals(1.0, zero.distanceTo(Vector3D(1.0, 0.0, 0.0))) + assertEquals(kotlin.math.sqrt(5.000001), Vector3D(1.0, -2.0, 0.001).distanceTo(zero)) + assertEquals(0.0, Vector3D(1.0, -2.0, 0.001).distanceTo(Vector3D(1.0, -2.0, 0.001))) + assertEquals(0.0, Vector3D(1.0, 0.0, 0.0).distanceTo(Vector3D(1.0, 0.0, 0.0))) + assertEquals(kotlin.math.sqrt(2.0), Vector3D(1.0, 0.0, 0.0).distanceTo(Vector3D(1.0, 1.0, 1.0))) + assertEquals(3.1622778182822584, Vector3D(0.0, 1.0, 0.0).distanceTo(Vector3D(1.0, -2.0, 0.001))) + assertEquals(0.0, Vector3D(1.0, -2.0, 0.001).distanceTo(Vector3D(1.0, -2.0, 0.001))) + assertEquals(9.695050335093676, Vector3D(1.0, 2.0, 3.0).distanceTo(Vector3D(7.0, -5.0, 0.001))) + } + } + + @Test + fun norm() { + with(Euclidean3DSpace) { + assertEquals(0.0, zero.norm()) + assertEquals(1.0, Vector3D(1.0, 0.0, 0.0).norm()) + assertEquals(kotlin.math.sqrt(3.0), Vector3D(1.0, 1.0, 1.0).norm()) + assertEquals(kotlin.math.sqrt(5.000001), Vector3D(1.0, -2.0, 0.001).norm()) + } + } + + @Test + fun dotProduct() { + with(Euclidean3DSpace) { + assertEquals(0.0, zero dot zero) + assertEquals(0.0, zero dot Vector3D(1.0, 0.0, 0.0)) + assertEquals(0.0, Vector3D(1.0, -2.0, 0.001) dot zero) + + assertEquals(1.0, Vector3D(1.0, 0.0, 0.0) dot Vector3D(1.0, 0.0, 0.0)) + assertEquals(1.0, Vector3D(1.0, 0.0, 0.0) dot Vector3D(1.0, 1.0, 1.0)) + assertEquals(-2.0, Vector3D(0.0, 1.0, 0.0) dot Vector3D(1.0, -2.0, 0.001)) + assertEquals(3.0, Vector3D(1.0, 1.0, 1.0) dot Vector3D(1.0, 1.0, 1.0)) + assertEquals(5.000001, Vector3D(1.0, -2.0, 0.001) dot Vector3D(1.0, -2.0, 0.001)) + + assertEquals(-2.997, Vector3D(1.0, 2.0, 3.0) dot Vector3D(7.0, -5.0, 0.001)) + } + } + + @Test + fun add() { + with(Euclidean3DSpace) { + assertVectorEquals( + Vector3D(1.0, -2.0, 0.001), + Vector3D(1.0, -2.0, 0.001) + zero + ) + assertVectorEquals( + Vector3D(8.0, -3.0, 3.001), + Vector3D(1.0, 2.0, 3.0) + Vector3D(7.0, -5.0, 0.001) + ) + } + } + + @Test + fun multiply() { + with(Euclidean3DSpace) { + assertVectorEquals(Vector3D(2.0, -4.0, 0.0), Vector3D(1.0, -2.0, 0.0) * 2) + } + } +} \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt new file mode 100644 index 000000000..cc940035f --- /dev/null +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt @@ -0,0 +1,60 @@ +package space.kscience.kmath.geometry + +import kotlin.test.Test +import kotlin.test.assertTrue + +internal class ProjectionAlongTest { + @Test + fun projectionIntoYEqualsX() { + with(Euclidean2DSpace) { + val normal = Vector2D(-2.0, 2.0) + val base = Vector2D(2.3, 2.3) + + assertVectorEquals(zero, projectAlong(zero, normal, base)) + + grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> + val d = (y - x) / 2.0 + assertVectorEquals(Vector2D(x + d, y - d), projectAlong(Vector2D(x, y), normal, base)) + } + } + } + + @Test + fun projectionOntoLine() { + with(Euclidean2DSpace) { + val a = 5.0 + val b = -3.0 + val c = -15.0 + val normal = Vector2D(-5.0, 3.0) + val base = Vector2D(3.0, 0.0) + + grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> + val xProj = (b * (b * x - a * y) - a * c) / (a * a + b * b) + val yProj = (a * (-b * x + a * y) - b * c) / (a * a + b * b) + assertVectorEquals(Vector2D(xProj, yProj), projectAlong(Vector2D(x, y), normal, base)) + } + } + } + + @Test + fun projectOntoPlane() { + val normal = Vector3D(1.0, 3.5, 0.07) + val base = Vector3D(2.0, -0.0037, 11.1111) + + with(Euclidean3DSpace) { + for (x in (-10.0..10.0).generateList(0.15)) { + for (y in (-10.0..10.0).generateList(0.15)) { + for (z in (-10.0..10.0).generateList(0.15)) { + val v = Vector3D(x, y, z) + val result = projectAlong(v, normal, base) + + // assert that result is on plane + assertTrue(isOrthogonal(result - base, normal)) + // assert that PV vector is collinear to normal vector + assertTrue(isCollinear(v - result, normal)) + } + } + } + } + } +} \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt new file mode 100644 index 000000000..1190b156d --- /dev/null +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt @@ -0,0 +1,82 @@ +package space.kscience.kmath.geometry + +import kotlin.test.Test +import kotlin.test.assertTrue + +internal class ProjectionOntoLineTest { + @Test + fun projectionIntoOx() { + with(Euclidean2DSpace) { + val ox = Line(zero, Vector2D(1.0, 0.0)) + + grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> + assertVectorEquals(Vector2D(x, 0.0), projectToLine(Vector2D(x, y), ox)) + } + } + } + + @Test + fun projectionIntoOy() { + with(Euclidean2DSpace) { + val line = Line(zero, Vector2D(0.0, 1.0)) + + grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> + assertVectorEquals(Vector2D(0.0, y), projectToLine(Vector2D(x, y), line)) + } + } + } + + @Test + fun projectionIntoYEqualsX() { + with(Euclidean2DSpace) { + val line = Line(zero, Vector2D(1.0, 1.0)) + + assertVectorEquals(zero, projectToLine(zero, line)) + + grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> + val d = (y - x) / 2.0 + assertVectorEquals(Vector2D(x + d, y - d), projectToLine(Vector2D(x, y), line)) + } + } + } + + @Test + fun projectionOntoLine2d() { + with(Euclidean2DSpace) { + val a = 5.0 + val b = -3.0 + val c = -15.0 + val line = Line(Vector2D(3.0, 0.0), Vector2D(3.0, 5.0)) + + grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> + val xProj = (b * (b * x - a * y) - a * c) / (a * a + b * b) + val yProj = (a * (-b * x + a * y) - b * c) / (a * a + b * b) + assertVectorEquals(Vector2D(xProj, yProj), projectToLine(Vector2D(x, y), line)) + } + } + } + + @Test + fun projectionOntoLine3d() { + val line = Line3D( + base = Vector3D(1.0, 3.5, 0.07), + direction = Vector3D(2.0, -0.0037, 11.1111) + ) + + with(Euclidean3DSpace) { + for (x in (-10.0..10.0).generateList(0.15)) { + for (y in (-10.0..10.0).generateList(0.15)) { + for (z in (-10.0..10.0).generateList(0.15)) { + val v = Vector3D(x, y, z) + val result = projectToLine(v, line) + + // assert that result is on line + assertTrue(isCollinear(result - line.base, line.direction)) + // assert that PV vector is orthogonal to direction vector + assertTrue(isOrthogonal(v - result, line.direction)) + } + } + } + } + } +} \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt new file mode 100644 index 000000000..647004f43 --- /dev/null +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt @@ -0,0 +1,36 @@ +package space.kscience.kmath.geometry + +import space.kscience.kmath.structures.asSequence +import space.kscience.kmath.structures.toList +import kotlin.test.assertEquals +import kotlin.test.Test + +internal class Vector2DTest { + private val vector = Vector2D(1.0, -7.999) + + @Test + fun getSize() { + assertEquals(2, vector.size) + } + + @Test + fun get() { + assertEquals(1.0, vector[0]) + assertEquals(-7.999, vector[1]) + } + + @Test + operator fun iterator() { + assertEquals(listOf(1.0, -7.999), vector.toList()) + } + + @Test + fun getX() { + assertEquals(1.0, vector.x) + } + + @Test + fun getY() { + assertEquals(-7.999, vector.y) + } +} \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt new file mode 100644 index 000000000..83271160f --- /dev/null +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt @@ -0,0 +1,41 @@ +package space.kscience.kmath.geometry + +import space.kscience.kmath.structures.toList +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class Vector3DTest { + private val vector = Vector3D(1.0, -7.999, 0.001) + + @Test + fun getSize() { + assertEquals(3, vector.size) + } + + @Test + fun get() { + assertEquals(1.0, vector[0]) + assertEquals(-7.999, vector[1]) + assertEquals(0.001, vector[2]) + } + + @Test + operator fun iterator() { + assertEquals(listOf(1.0, -7.999, 0.001), vector.toList()) + } + + @Test + fun getX() { + assertEquals(1.0, vector.x) + } + + @Test + fun getY() { + assertEquals(-7.999, vector.y) + } + + @Test + fun getZ() { + assertEquals(0.001, vector.z) + } +} \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt new file mode 100644 index 000000000..773d6d90c --- /dev/null +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -0,0 +1,41 @@ +package space.kscience.kmath.geometry + +import kotlin.math.abs +import kotlin.test.assertEquals + +fun ClosedRange.generateList(step: Double): List = generateSequence(start) { previous -> + if (previous == Double.POSITIVE_INFINITY) return@generateSequence null + val next = previous + step + if (next > endInclusive) null else next +}.toList() + +fun grid( + xRange: ClosedRange, + yRange: ClosedRange, + step: Double +): List> { + val xs = xRange.generateList(step) + val ys = yRange.generateList(step) + + return xs.flatMap { x -> ys.map { y -> x to y } } +} + +fun assertVectorEquals(expected: Vector2D, actual: Vector2D, eps: Double = 1e-6) { + assertEquals(expected.x, actual.x, eps) + assertEquals(expected.y, actual.y, eps) +} + +fun assertVectorEquals(expected: Vector3D, actual: Vector3D, eps: Double = 1e-6) { + assertEquals(expected.x, actual.x, eps) + assertEquals(expected.y, actual.y, eps) + assertEquals(expected.z, actual.z, eps) +} + +fun GeometrySpace.isCollinear(a: V, b: V, eps: Double = 1e-6): Boolean { + val aDist = a.distanceTo(zero) + val bDist = b.distanceTo(zero) + return abs(aDist) < eps || abs(bDist) < eps || abs(abs((a dot b) / (aDist * bDist)) - 1) < eps +} + +fun GeometrySpace.isOrthogonal(a: V, b: V, eps: Double = 1e-6): Boolean = + abs(a dot b) < eps From 603db46eb848e1ac3d1c7015bfe25f74fc78f3e2 Mon Sep 17 00:00:00 2001 From: Veniamin Viflyantsev Date: Tue, 17 Aug 2021 21:10:26 +0300 Subject: [PATCH 2/4] increased test timeouts in geometry project --- kmath-geometry/build.gradle.kts | 14 ++++++++++++++ .../kscience/kmath/geometry/ProjectionAlongTest.kt | 7 ++++--- .../kmath/geometry/ProjectionOntoLineTest.kt | 7 ++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts index 7eb814683..653d113a6 100644 --- a/kmath-geometry/build.gradle.kts +++ b/kmath-geometry/build.gradle.kts @@ -4,6 +4,20 @@ plugins { id("ru.mipt.npm.gradle.native") } +kotlin.js { + nodejs { + testTask { + useMocha().timeout = "5000" + } + } + + browser { + testTask { + useMocha().timeout = "5000" + } + } +} + kotlin.sourceSets.commonMain { dependencies { api(project(":kmath-core")) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt index cc940035f..78ce98dc4 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt @@ -42,9 +42,10 @@ internal class ProjectionAlongTest { val base = Vector3D(2.0, -0.0037, 11.1111) with(Euclidean3DSpace) { - for (x in (-10.0..10.0).generateList(0.15)) { - for (y in (-10.0..10.0).generateList(0.15)) { - for (z in (-10.0..10.0).generateList(0.15)) { + val testDomain = (-10.0..10.0).generateList(0.15) + for (x in testDomain) { + for (y in testDomain) { + for (z in testDomain) { val v = Vector3D(x, y, z) val result = projectAlong(v, normal, base) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt index 1190b156d..ec74ff59b 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt @@ -64,9 +64,10 @@ internal class ProjectionOntoLineTest { ) with(Euclidean3DSpace) { - for (x in (-10.0..10.0).generateList(0.15)) { - for (y in (-10.0..10.0).generateList(0.15)) { - for (z in (-10.0..10.0).generateList(0.15)) { + val testDomain = (-10.0..10.0).generateList(0.15) + for (x in testDomain) { + for (y in testDomain) { + for (z in testDomain) { val v = Vector3D(x, y, z) val result = projectToLine(v, line) From f271ded526ca5c3dcc07a0afed900a60ca181299 Mon Sep 17 00:00:00 2001 From: Ven Date: Tue, 17 Aug 2021 21:17:02 +0300 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Iaroslav Postovalov <38042667+CommanderTvis@users.noreply.github.com> --- .../kscience/kmath/geometry/Projections.kt | 6 ++--- .../kmath/geometry/Euclidean2DSpaceTest.kt | 4 ++-- .../kmath/geometry/Euclidean3DSpaceTest.kt | 4 ++-- .../kmath/geometry/ProjectionAlongTest.kt | 2 +- .../kmath/geometry/ProjectionOntoLineTest.kt | 2 +- .../kscience/kmath/geometry/Vector2DTest.kt | 10 ++++----- .../kscience/kmath/geometry/Vector3DTest.kt | 12 +++++----- .../kscience/kmath/geometry/testUtils.kt | 22 +++++++++---------- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt index d13ef03a1..205bc17e7 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Projections.kt @@ -1,7 +1,7 @@ package space.kscience.kmath.geometry /** - * Project vector to a line + * Project vector onto a line. * @param vector to project * @param line line to which vector should be projected */ @@ -10,8 +10,8 @@ public fun GeometrySpace.projectToLine(vector: V, line: Line) } /** - * Project vector to a hyper-plane, which is defined by a normal and base - * In 2d case it is projection to a line, in 3d case it is projection to a plane + * Project vector onto a hyperplane, which is defined by a normal and base. + * In 2D case it is the projection to a line, in 3d case it is the one to a plane. * @param vector to project * @param normal normal (perpendicular) vector to a hyper-plane to which vector should be projected * @param base point belonging to a hyper-plane to which vector should be projected diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt index 6d5ae9948..5913b2fa9 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt @@ -6,7 +6,7 @@ import kotlin.test.assertEquals internal class Euclidean2DSpaceTest { @Test - fun getZero() { + fun zero() { assertVectorEquals(Vector2D(0.0, 0.0), Euclidean2DSpace.zero) } @@ -59,4 +59,4 @@ internal class Euclidean2DSpaceTest { assertVectorEquals(Vector2D(300.0, 0.0003), Vector2D(100.0, 0.0001) * 3) } } -} \ No newline at end of file +} diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt index 9cce44c65..2c74cbd27 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt @@ -5,7 +5,7 @@ import kotlin.test.assertEquals internal class Euclidean3DSpaceTest { @Test - fun getZero() { + fun zero() { assertVectorEquals(Vector3D(0.0, 0.0, 0.0), Euclidean3DSpace.zero) } @@ -71,4 +71,4 @@ internal class Euclidean3DSpaceTest { assertVectorEquals(Vector3D(2.0, -4.0, 0.0), Vector3D(1.0, -2.0, 0.0) * 2) } } -} \ No newline at end of file +} diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt index 78ce98dc4..65291ee4e 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt @@ -58,4 +58,4 @@ internal class ProjectionAlongTest { } } } -} \ No newline at end of file +} diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt index ec74ff59b..0f74e1efb 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt @@ -80,4 +80,4 @@ internal class ProjectionOntoLineTest { } } } -} \ No newline at end of file +} diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt index 647004f43..84b1f4fd6 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt @@ -9,7 +9,7 @@ internal class Vector2DTest { private val vector = Vector2D(1.0, -7.999) @Test - fun getSize() { + fun size() { assertEquals(2, vector.size) } @@ -20,17 +20,17 @@ internal class Vector2DTest { } @Test - operator fun iterator() { + fun iterator() { assertEquals(listOf(1.0, -7.999), vector.toList()) } @Test - fun getX() { + fun x() { assertEquals(1.0, vector.x) } @Test - fun getY() { + fun y() { assertEquals(-7.999, vector.y) } -} \ No newline at end of file +} diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt index 83271160f..717e78871 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt @@ -8,7 +8,7 @@ internal class Vector3DTest { private val vector = Vector3D(1.0, -7.999, 0.001) @Test - fun getSize() { + fun size() { assertEquals(3, vector.size) } @@ -20,22 +20,22 @@ internal class Vector3DTest { } @Test - operator fun iterator() { + fun iterator() { assertEquals(listOf(1.0, -7.999, 0.001), vector.toList()) } @Test - fun getX() { + fun x() { assertEquals(1.0, vector.x) } @Test - fun getY() { + fun y() { assertEquals(-7.999, vector.y) } @Test - fun getZ() { + fun z() { assertEquals(0.001, vector.z) } -} \ No newline at end of file +} diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index 773d6d90c..1277c0130 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -20,22 +20,22 @@ fun grid( return xs.flatMap { x -> ys.map { y -> x to y } } } -fun assertVectorEquals(expected: Vector2D, actual: Vector2D, eps: Double = 1e-6) { - assertEquals(expected.x, actual.x, eps) - assertEquals(expected.y, actual.y, eps) +fun assertVectorEquals(expected: Vector2D, actual: Vector2D, absoluteTolerance: Double = 1e-6) { + assertEquals(expected.x, actual.x, absoluteTolerance) + assertEquals(expected.y, actual.y, absoluteTolerance) } -fun assertVectorEquals(expected: Vector3D, actual: Vector3D, eps: Double = 1e-6) { - assertEquals(expected.x, actual.x, eps) - assertEquals(expected.y, actual.y, eps) - assertEquals(expected.z, actual.z, eps) +fun assertVectorEquals(expected: Vector3D, actual: Vector3D, absoluteTolerance: Double = 1e-6) { + assertEquals(expected.x, actual.x, absoluteTolerance) + assertEquals(expected.y, actual.y, absoluteTolerance) + assertEquals(expected.z, actual.z, absoluteTolerance) } -fun GeometrySpace.isCollinear(a: V, b: V, eps: Double = 1e-6): Boolean { +fun GeometrySpace.isCollinear(a: V, b: V, absoluteTolerance: Double = 1e-6): Boolean { val aDist = a.distanceTo(zero) val bDist = b.distanceTo(zero) - return abs(aDist) < eps || abs(bDist) < eps || abs(abs((a dot b) / (aDist * bDist)) - 1) < eps + return abs(aDist) < absoluteTolerance || abs(bDist) < absoluteTolerance || abs(abs((a dot b) / (aDist * bDist)) - 1) < absoluteTolerance } -fun GeometrySpace.isOrthogonal(a: V, b: V, eps: Double = 1e-6): Boolean = - abs(a dot b) < eps +fun GeometrySpace.isOrthogonal(a: V, b: V, absoluteTolerance: Double = 1e-6): Boolean = + abs(a dot b) < absoluteTolerance From 47ac2dd0a9959072c1e9cc19e78cc88d99f1c68f Mon Sep 17 00:00:00 2001 From: Veniamin Viflyantsev Date: Tue, 17 Aug 2021 23:47:52 +0300 Subject: [PATCH 4/4] returned back test timeouts, decrease number of cases that tests check to make it faster --- kmath-geometry/build.gradle.kts | 14 -------------- .../kscience/kmath/geometry/ProjectionAlongTest.kt | 2 +- .../kmath/geometry/ProjectionOntoLineTest.kt | 2 +- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts index 653d113a6..7eb814683 100644 --- a/kmath-geometry/build.gradle.kts +++ b/kmath-geometry/build.gradle.kts @@ -4,20 +4,6 @@ plugins { id("ru.mipt.npm.gradle.native") } -kotlin.js { - nodejs { - testTask { - useMocha().timeout = "5000" - } - } - - browser { - testTask { - useMocha().timeout = "5000" - } - } -} - kotlin.sourceSets.commonMain { dependencies { api(project(":kmath-core")) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt index 65291ee4e..55fc39aad 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt @@ -42,7 +42,7 @@ internal class ProjectionAlongTest { val base = Vector3D(2.0, -0.0037, 11.1111) with(Euclidean3DSpace) { - val testDomain = (-10.0..10.0).generateList(0.15) + val testDomain = (-10.0..10.0).generateList(0.43) for (x in testDomain) { for (y in testDomain) { for (z in testDomain) { diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt index 0f74e1efb..ab6ef3628 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt @@ -64,7 +64,7 @@ internal class ProjectionOntoLineTest { ) with(Euclidean3DSpace) { - val testDomain = (-10.0..10.0).generateList(0.15) + val testDomain = (-10.0..10.0).generateList(0.43) for (x in testDomain) { for (y in testDomain) { for (z in testDomain) {