From f6f74b54f60ecfd5b772b6cd82100fe136a4ba52 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 30 May 2023 13:56:14 +0300 Subject: [PATCH] Fix cone segmenta and cone surface representation --- demo/playground/src/jvmMain/kotlin/shapes.kt | 8 +-- .../kscience/visionforge/solid/ConeSegment.kt | 49 ++++++++----------- .../kscience/visionforge/solid/ConeSurface.kt | 28 +++++------ .../visionforge/solid/three/ThreePlugin.kt | 2 +- 4 files changed, 40 insertions(+), 47 deletions(-) diff --git a/demo/playground/src/jvmMain/kotlin/shapes.kt b/demo/playground/src/jvmMain/kotlin/shapes.kt index bcd4f73a..1c702c5e 100644 --- a/demo/playground/src/jvmMain/kotlin/shapes.kt +++ b/demo/playground/src/jvmMain/kotlin/shapes.kt @@ -1,10 +1,10 @@ package space.kscience.visionforge.examples -import kotlin.math.PI import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.* +import kotlin.math.PI -fun main() = makeVisionFile{ +fun main() = makeVisionFile { vision("canvas") { solid { ambientLight() @@ -30,9 +30,9 @@ fun main() = makeVisionFile{ } - tube(30,20, 20){ + cylinder(30,20, name = "cylinder"){ detail = 31 - y = - 220 + y = -220 } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt index 6e2677af..94ea5eaf 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt @@ -22,60 +22,53 @@ public class ConeSegment( public val phi: Float = PI2, ) : SolidBase(), GeometrySolid { + init { - require(bottomRadius > 0) { "Bottom radius must be positive" } - require(topRadius > 0) { "Top radius must be positive" } + require(bottomRadius > 0) { "Cone segment bottom radius must be positive" } + require(height > 0) { "Cone segment height must be positive" } + require(topRadius >= 0) { "Cone segment top radius must be non-negative" } + //require(startAngle >= 0) + require(phi in (0f..(PI2))) } override fun toGeometry(geometryBuilder: GeometryBuilder) { - - val segments: Int = detail ?: 32 - require(segments >= 4) { "The number of segments in cone segment is too small" } - + val segments = detail ?: 32 + require(segments >= 4) { "The number of segments in cone is too small" } val angleStep = phi / (segments - 1) - /** - * Top and bottom shape - */ fun shape(r: Float, z: Float): List = (0 until segments).map { i -> Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } - with(geometryBuilder) { - - // top and bottom faces - val bottomOuterPoints: List = shape(topRadius, -height / 2) - val upperOuterPoints: List = shape(bottomRadius, height / 2) + geometryBuilder.apply { + //creating shape in x-y plane with z = 0 + val bottomPoints = shape(bottomRadius, -height / 2) + val topPoints = shape(topRadius, height / 2) //outer face for (it in 1 until segments) { - face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1]) + face4(bottomPoints[it - 1], bottomPoints[it], topPoints[it], topPoints[it - 1]) } - //if the cone is closed if (phi == PI2) { - face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last()) + face4(bottomPoints.last(), bottomPoints[0], topPoints[0], topPoints.last()) } - - //top and bottom cups val zeroBottom = Point3D(0f, 0f, -height / 2) - val zeroTop = Point3D(0f, 0f, height / 2) + val zeroTop = Point3D(0f, 0f, +height / 2) for (it in 1 until segments) { - face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) - face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop) + face(bottomPoints[it - 1], zeroBottom, bottomPoints[it]) + face(topPoints[it - 1], topPoints[it], zeroTop) } - // closed surface if (phi == PI2) { - face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) - face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop) + face(bottomPoints.last(), zeroBottom, bottomPoints[0]) + face(topPoints.last(), topPoints[0], zeroTop) } else { - face4(zeroTop, zeroBottom, bottomOuterPoints[0], upperOuterPoints[0]) - face4(zeroTop, zeroBottom, bottomOuterPoints.last(), upperOuterPoints.last()) + face4(zeroTop, zeroBottom, bottomPoints[0], topPoints[0]) + face4(zeroTop, zeroBottom, bottomPoints.last(), topPoints.last()) } } } - } @VisionBuilder diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt index 2a6bcdc5..75ff2161 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt @@ -21,8 +21,8 @@ public class ConeSurface( public val height: Float, public val topRadius: Float, public val topInnerRadius: Float, - public val startAngle: Float = 0f, - public val angle: Float = PI2, + public val phiStart: Float = 0f, + public val phi: Float = PI2, ) : SolidBase(), GeometrySolid { init { @@ -30,16 +30,16 @@ public class ConeSurface( require(height > 0) { "Cone surface height must be positive" } require(bottomInnerRadius >= 0) { "Cone surface bottom inner radius must be non-negative" } //require(startAngle >= 0) - require(angle in (0f..(PI2))) + require(phi in (0f..(PI2))) } override fun toGeometry(geometryBuilder: GeometryBuilder) { val segments = detail ?: 32 require(segments >= 4) { "The number of segments in tube is too small" } - val angleStep = angle / (segments - 1) + val angleStep = phi / (segments - 1) fun shape(r: Float, z: Float): List = (0 until segments).map { i -> - Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) + Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } geometryBuilder.apply { @@ -52,17 +52,17 @@ public class ConeSurface( face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1]) } - if (angle == PI2) { + if (phi == PI2) { face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) } if (bottomInnerRadius == 0f) { - val zeroBottom = Point3D(0f, 0f, 0f) - val zeroTop = Point3D(0f, 0f, height) + val zeroBottom = Point3D(0f, 0f, -height / 2) + val zeroTop = Point3D(0f, 0f, height / 2) (1 until segments).forEach { face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop) } - if (angle == PI2) { + if (phi == PI2) { face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) face(topOuterPoints.last(), topOuterPoints[0], zeroTop) } else { @@ -96,7 +96,7 @@ public class ConeSurface( topOuterPoints[it] ) } - if (angle == PI2) { + if (phi == PI2) { face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0]) face4( bottomInnerPoints.last(), @@ -135,8 +135,8 @@ public inline fun MutableVisionContainer.tube( height = height.toFloat(), topRadius = radius.toFloat(), topInnerRadius = innerRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() + phiStart = startAngle.toFloat(), + phi = angle.toFloat() ).apply(block).also { setChild(name, it) } @VisionBuilder @@ -156,6 +156,6 @@ public inline fun MutableVisionContainer.coneSurface( height = height.toFloat(), topRadius = topOuterRadius.toFloat(), topInnerRadius = topInnerRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() + phiStart = startAngle.toFloat(), + phi = angle.toFloat() ).apply(block).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 1913e332..234ded6f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -34,7 +34,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { objectFactories[Box::class] = ThreeBoxFactory objectFactories[Convex::class] = ThreeConvexFactory objectFactories[Sphere::class] = ThreeSphereFactory - objectFactories[ConeSegment::class] = ThreeConeFactory +// objectFactories[ConeSegment::class] = ThreeConeFactory objectFactories[PolyLine::class] = ThreeSmartLineFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory