forked from kscience/visionforge
Fix cone segmenta and cone surface representation
This commit is contained in:
parent
33778801b6
commit
f6f74b54f6
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,60 +22,53 @@ public class ConeSegment(
|
||||
public val phi: Float = PI2,
|
||||
) : SolidBase<ConeSegment>(), 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 <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
|
||||
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<Point3D> = (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<Point3D> = shape(topRadius, -height / 2)
|
||||
val upperOuterPoints: List<Point3D> = 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
|
||||
|
@ -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<ConeSurface>(), 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 <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
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<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 {
|
||||
@ -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<Solid>.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<Solid>.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) }
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user