From e2fa39af086b6733fca6cbed8097dff51cfc0ef1 Mon Sep 17 00:00:00 2001 From: Abe Pazos Date: Sun, 13 Jul 2025 11:59:44 +0200 Subject: [PATCH] [orx-composition] Add test and demo for PR#360 --- .../src/demo/kotlin/DemoClipping.kt | 43 ++++++++++++++++ .../src/commonTest/kotlin/TestComposition.kt | 51 ++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 openrndr-demos/src/demo/kotlin/DemoClipping.kt diff --git a/openrndr-demos/src/demo/kotlin/DemoClipping.kt b/openrndr-demos/src/demo/kotlin/DemoClipping.kt new file mode 100644 index 00000000..c224aa3b --- /dev/null +++ b/openrndr-demos/src/demo/kotlin/DemoClipping.kt @@ -0,0 +1,43 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extra.composition.ClipMode +import org.openrndr.extra.composition.composition +import org.openrndr.extra.composition.drawComposition +import org.openrndr.math.Vector2 +import org.openrndr.shape.Circle +import org.openrndr.shape.LineSegment +import org.openrndr.shape.Shape + +fun main() = application { + program { + val outline = Shape( + listOf( + Circle(drawer.bounds.center, 70.0).contour.reversed, + Circle(drawer.bounds.center, 100.0).contour, + ) + ) + + val radius = outline.bounds.dimensions.length / 2 + val off = outline.bounds.center + val num = radius.toInt() + + val svg = drawComposition { + lineSegments(List(num) { segNum -> + val yNorm = (segNum / (num - 1.0)) + val x = ((segNum % 2) * 2.0 - 1.0) * radius + val y = (yNorm * 2.0 - 1.0) * radius + val start = Vector2(-x, y) + off + val end = Vector2(x, y) + off + LineSegment(start, end) + }) + clipMode = ClipMode.INTERSECT + shape(outline) + } + extend { + drawer.clear(ColorRGBa.PINK) + drawer.fill = null + drawer.shape(outline) + drawer.composition(svg) + } + } +} \ No newline at end of file diff --git a/orx-composition/src/commonTest/kotlin/TestComposition.kt b/orx-composition/src/commonTest/kotlin/TestComposition.kt index 21ab4391..f22ac170 100644 --- a/orx-composition/src/commonTest/kotlin/TestComposition.kt +++ b/orx-composition/src/commonTest/kotlin/TestComposition.kt @@ -1,7 +1,14 @@ package org.openrndr.extra.composition +import org.openrndr.math.Vector2 +import org.openrndr.shape.Circle +import org.openrndr.shape.LineSegment +import org.openrndr.shape.Rectangle import org.openrndr.shape.Shape -import kotlin.test.* +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue class TestComposition { val composition = let { _ -> @@ -35,4 +42,46 @@ class TestComposition { assertNull(composition.findImage("outer")) assertNull(composition.findImage("shape")) } +} + +class TestCompositionIntersections { + val bounds = Rectangle(Vector2.ZERO, 640.0, 480.0) + val outline = Shape( + listOf( + Circle(bounds.center, 70.0).contour.reversed, + Circle(bounds.center, 100.0).contour, + ) + ) + + val radius = outline.bounds.dimensions.length / 2 + val off = outline.bounds.center + val num = radius.toInt() + + @Test + fun `use a shape as a mask for line segments`() { + // Make sure intersections do not fail randomly, which was fixed in + // https://github.com/openrndr/orx/commit/e8f50b3dd153ed82de121e9017cf42f6ea95ac8e + val svg = List(100) { + drawComposition { + lineSegments(List(num) { segNum -> + val yNorm = (segNum / (num - 1.0)) + val x = ((segNum % 2) * 2.0 - 1.0) * radius + val y = (yNorm * 2.0 - 1.0) * radius + val start = Vector2(-x, y) + off + val end = Vector2(x, y) + off + LineSegment(start, end) + }) + clipMode = ClipMode.INTERSECT + shape(outline) + } + } + + val shapes = svg[50].findShapes() + val dimensions = svg[50].bounds.dimensions + + assertTrue(shapes.isNotEmpty()) + assertTrue(shapes.first().shape.contours.isNotEmpty()) + assertTrue(dimensions.x > 0.0) + assertTrue(dimensions.y > 0.0) + } } \ No newline at end of file