forked from kscience/visionforge
Fix cone segmenta and cone surface representation
This commit is contained in:
parent
33778801b6
commit
f6f74b54f6
@ -1,8 +1,8 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
import kotlin.math.PI
|
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
|
import kotlin.math.PI
|
||||||
|
|
||||||
fun main() = makeVisionFile {
|
fun main() = makeVisionFile {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
@ -30,7 +30,7 @@ fun main() = makeVisionFile{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tube(30,20, 20){
|
cylinder(30,20, name = "cylinder"){
|
||||||
detail = 31
|
detail = 31
|
||||||
y = -220
|
y = -220
|
||||||
}
|
}
|
||||||
|
@ -22,60 +22,53 @@ public class ConeSegment(
|
|||||||
public val phi: Float = PI2,
|
public val phi: Float = PI2,
|
||||||
) : SolidBase<ConeSegment>(), GeometrySolid {
|
) : SolidBase<ConeSegment>(), GeometrySolid {
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
require(bottomRadius > 0) { "Bottom radius must be positive" }
|
require(bottomRadius > 0) { "Cone segment bottom radius must be positive" }
|
||||||
require(topRadius > 0) { "Top 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 <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||||
|
val segments = detail ?: 32
|
||||||
val segments: Int = detail ?: 32
|
require(segments >= 4) { "The number of segments in cone is too small" }
|
||||||
require(segments >= 4) { "The number of segments in cone segment is too small" }
|
|
||||||
|
|
||||||
val angleStep = phi / (segments - 1)
|
val angleStep = phi / (segments - 1)
|
||||||
|
|
||||||
/**
|
|
||||||
* Top and bottom shape
|
|
||||||
*/
|
|
||||||
fun shape(r: Float, z: Float): List<Point3D> = (0 until segments).map { i ->
|
fun shape(r: Float, z: Float): List<Point3D> = (0 until segments).map { i ->
|
||||||
Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z)
|
Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z)
|
||||||
}
|
}
|
||||||
|
|
||||||
with(geometryBuilder) {
|
geometryBuilder.apply {
|
||||||
|
|
||||||
// top and bottom faces
|
|
||||||
val bottomOuterPoints: List<Point3D> = shape(topRadius, -height / 2)
|
|
||||||
val upperOuterPoints: List<Point3D> = shape(bottomRadius, height / 2)
|
|
||||||
|
|
||||||
|
//creating shape in x-y plane with z = 0
|
||||||
|
val bottomPoints = shape(bottomRadius, -height / 2)
|
||||||
|
val topPoints = shape(topRadius, height / 2)
|
||||||
//outer face
|
//outer face
|
||||||
for (it in 1 until segments) {
|
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) {
|
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 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) {
|
for (it in 1 until segments) {
|
||||||
face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it])
|
face(bottomPoints[it - 1], zeroBottom, bottomPoints[it])
|
||||||
face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop)
|
face(topPoints[it - 1], topPoints[it], zeroTop)
|
||||||
}
|
}
|
||||||
// closed surface
|
|
||||||
if (phi == PI2) {
|
if (phi == PI2) {
|
||||||
face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0])
|
face(bottomPoints.last(), zeroBottom, bottomPoints[0])
|
||||||
face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop)
|
face(topPoints.last(), topPoints[0], zeroTop)
|
||||||
} else {
|
} else {
|
||||||
face4(zeroTop, zeroBottom, bottomOuterPoints[0], upperOuterPoints[0])
|
face4(zeroTop, zeroBottom, bottomPoints[0], topPoints[0])
|
||||||
face4(zeroTop, zeroBottom, bottomOuterPoints.last(), upperOuterPoints.last())
|
face4(zeroTop, zeroBottom, bottomPoints.last(), topPoints.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
|
@ -21,8 +21,8 @@ public class ConeSurface(
|
|||||||
public val height: Float,
|
public val height: Float,
|
||||||
public val topRadius: Float,
|
public val topRadius: Float,
|
||||||
public val topInnerRadius: Float,
|
public val topInnerRadius: Float,
|
||||||
public val startAngle: Float = 0f,
|
public val phiStart: Float = 0f,
|
||||||
public val angle: Float = PI2,
|
public val phi: Float = PI2,
|
||||||
) : SolidBase<ConeSurface>(), GeometrySolid {
|
) : SolidBase<ConeSurface>(), GeometrySolid {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -30,16 +30,16 @@ public class ConeSurface(
|
|||||||
require(height > 0) { "Cone surface height must be positive" }
|
require(height > 0) { "Cone surface height must be positive" }
|
||||||
require(bottomInnerRadius >= 0) { "Cone surface bottom inner radius must be non-negative" }
|
require(bottomInnerRadius >= 0) { "Cone surface bottom inner radius must be non-negative" }
|
||||||
//require(startAngle >= 0)
|
//require(startAngle >= 0)
|
||||||
require(angle in (0f..(PI2)))
|
require(phi in (0f..(PI2)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||||
val segments = detail ?: 32
|
val segments = detail ?: 32
|
||||||
require(segments >= 4) { "The number of segments in tube is too small" }
|
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<Point3D> = (0 until segments).map { i ->
|
fun shape(r: Float, z: Float): List<Point3D> = (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 {
|
geometryBuilder.apply {
|
||||||
@ -52,17 +52,17 @@ public class ConeSurface(
|
|||||||
face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1])
|
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())
|
face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last())
|
||||||
}
|
}
|
||||||
if (bottomInnerRadius == 0f) {
|
if (bottomInnerRadius == 0f) {
|
||||||
val zeroBottom = Point3D(0f, 0f, 0f)
|
val zeroBottom = Point3D(0f, 0f, -height / 2)
|
||||||
val zeroTop = Point3D(0f, 0f, height)
|
val zeroTop = Point3D(0f, 0f, height / 2)
|
||||||
(1 until segments).forEach {
|
(1 until segments).forEach {
|
||||||
face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it])
|
face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it])
|
||||||
face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop)
|
face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop)
|
||||||
}
|
}
|
||||||
if (angle == PI2) {
|
if (phi == PI2) {
|
||||||
face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0])
|
face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0])
|
||||||
face(topOuterPoints.last(), topOuterPoints[0], zeroTop)
|
face(topOuterPoints.last(), topOuterPoints[0], zeroTop)
|
||||||
} else {
|
} else {
|
||||||
@ -96,7 +96,7 @@ public class ConeSurface(
|
|||||||
topOuterPoints[it]
|
topOuterPoints[it]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (angle == PI2) {
|
if (phi == PI2) {
|
||||||
face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0])
|
face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0])
|
||||||
face4(
|
face4(
|
||||||
bottomInnerPoints.last(),
|
bottomInnerPoints.last(),
|
||||||
@ -135,8 +135,8 @@ public inline fun MutableVisionContainer<Solid>.tube(
|
|||||||
height = height.toFloat(),
|
height = height.toFloat(),
|
||||||
topRadius = radius.toFloat(),
|
topRadius = radius.toFloat(),
|
||||||
topInnerRadius = innerRadius.toFloat(),
|
topInnerRadius = innerRadius.toFloat(),
|
||||||
startAngle = startAngle.toFloat(),
|
phiStart = startAngle.toFloat(),
|
||||||
angle = angle.toFloat()
|
phi = angle.toFloat()
|
||||||
).apply(block).also { setChild(name, it) }
|
).apply(block).also { setChild(name, it) }
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
@ -156,6 +156,6 @@ public inline fun MutableVisionContainer<Solid>.coneSurface(
|
|||||||
height = height.toFloat(),
|
height = height.toFloat(),
|
||||||
topRadius = topOuterRadius.toFloat(),
|
topRadius = topOuterRadius.toFloat(),
|
||||||
topInnerRadius = topInnerRadius.toFloat(),
|
topInnerRadius = topInnerRadius.toFloat(),
|
||||||
startAngle = startAngle.toFloat(),
|
phiStart = startAngle.toFloat(),
|
||||||
angle = angle.toFloat()
|
phi = angle.toFloat()
|
||||||
).apply(block).also { setChild(name, it) }
|
).apply(block).also { setChild(name, it) }
|
@ -34,7 +34,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
objectFactories[Box::class] = ThreeBoxFactory
|
objectFactories[Box::class] = ThreeBoxFactory
|
||||||
objectFactories[Convex::class] = ThreeConvexFactory
|
objectFactories[Convex::class] = ThreeConvexFactory
|
||||||
objectFactories[Sphere::class] = ThreeSphereFactory
|
objectFactories[Sphere::class] = ThreeSphereFactory
|
||||||
objectFactories[ConeSegment::class] = ThreeConeFactory
|
// objectFactories[ConeSegment::class] = ThreeConeFactory
|
||||||
objectFactories[PolyLine::class] = ThreeSmartLineFactory
|
objectFactories[PolyLine::class] = ThreeSmartLineFactory
|
||||||
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
|
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
|
||||||
objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory
|
objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory
|
||||||
|
Loading…
Reference in New Issue
Block a user