forked from kscience/visionforge
Add surface geometry
This commit is contained in:
parent
00213c089d
commit
c7640a686a
@ -1,6 +1,9 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.visionforge.solid.*
|
||||
import space.kscience.visionforge.solid.ambientLight
|
||||
import space.kscience.visionforge.solid.extruded
|
||||
import space.kscience.visionforge.solid.polygon
|
||||
import space.kscience.visionforge.solid.solid
|
||||
|
||||
fun main() = makeVisionFile {
|
||||
vision("canvas") {
|
||||
@ -12,8 +15,6 @@ fun main() = makeVisionFile {
|
||||
}
|
||||
layer(-30)
|
||||
layer(30)
|
||||
}.apply {
|
||||
edges(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,19 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
//fun main() = makeVisionFile {
|
||||
// vision("canvas") {
|
||||
// solid {
|
||||
// ambientLight()
|
||||
// surface("surface") {
|
||||
// shape{
|
||||
// polygon(8, 100)
|
||||
// layer(-30)
|
||||
// layer(30)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
import space.kscience.visionforge.solid.ambientLight
|
||||
import space.kscience.visionforge.solid.polygon
|
||||
import space.kscience.visionforge.solid.solid
|
||||
import space.kscience.visionforge.solid.surface
|
||||
|
||||
fun main() = makeVisionFile {
|
||||
vision("canvas") {
|
||||
solid {
|
||||
ambientLight()
|
||||
surface("surface") {
|
||||
layer(0, {polygon(8,10)}, {polygon(8,20)})
|
||||
layer(10, {polygon(8,10)}, {polygon(8,30)})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,37 +9,8 @@ import space.kscience.kmath.geometry.component2
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.setChild
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
|
||||
public typealias Shape2D = List<Float32Vector2D>
|
||||
|
||||
@Serializable
|
||||
public class Shape2DBuilder(private val points: ArrayList<Float32Vector2D> = ArrayList()) {
|
||||
|
||||
public fun point(x: Number, y: Number) {
|
||||
points.add(Float32Vector2D(x, y))
|
||||
}
|
||||
|
||||
public fun build(): Shape2D = points
|
||||
}
|
||||
|
||||
public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
||||
require(vertices > 2) { "Polygon must have more than 2 vertices" }
|
||||
val angle = 2 * PI / vertices
|
||||
for (i in 0 until vertices) {
|
||||
point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A layer for extruded shape
|
||||
*/
|
||||
@Serializable
|
||||
public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
|
||||
|
||||
/**
|
||||
* An extruded shape with the same number of points on each layer.
|
||||
*/
|
||||
@ -50,6 +21,12 @@ public class Extruded(
|
||||
public val layers: List<Layer>,
|
||||
) : SolidBase<Extruded>(), GeometrySolid {
|
||||
|
||||
/**
|
||||
* A layer for extruded shape
|
||||
*/
|
||||
@Serializable
|
||||
public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
|
||||
|
||||
init {
|
||||
require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" }
|
||||
}
|
||||
@ -72,6 +49,8 @@ public class Extruded(
|
||||
var lowerLayer = layers.first()
|
||||
var upperLayer: List<Float32Vector3D>
|
||||
|
||||
geometryBuilder.cap(layers.first().reversed())
|
||||
|
||||
for (i in (1 until layers.size)) {
|
||||
upperLayer = layers[i]
|
||||
for (j in (0 until shape.size - 1)) {
|
||||
@ -93,7 +72,7 @@ public class Extruded(
|
||||
)
|
||||
lowerLayer = upperLayer
|
||||
}
|
||||
geometryBuilder.cap(layers.first().reversed())
|
||||
|
||||
geometryBuilder.cap(layers.last())
|
||||
}
|
||||
|
||||
@ -102,10 +81,12 @@ public class Extruded(
|
||||
public var layers: MutableList<Layer> = ArrayList(),
|
||||
public val properties: MutableMeta = MutableMeta(),
|
||||
) {
|
||||
@VisionBuilder
|
||||
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||
this.shape = Shape2DBuilder().apply(block).build()
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) {
|
||||
layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat()))
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
public typealias Shape2D = List<Float32Vector2D>
|
||||
|
||||
@Serializable
|
||||
public class Shape2DBuilder(private val points: ArrayList<Float32Vector2D> = ArrayList()) {
|
||||
|
||||
public fun point(x: Number, y: Number) {
|
||||
points.add(Float32Vector2D(x, y))
|
||||
}
|
||||
|
||||
public fun build(): Shape2D = points
|
||||
}
|
||||
|
||||
public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
||||
require(vertices > 2) { "Polygon must have more than 2 vertices" }
|
||||
val angle = 2 * PI / vertices
|
||||
for (i in 0 until vertices) {
|
||||
point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i))
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer<Sol
|
||||
subclass(ConeSurface.serializer())
|
||||
subclass(Convex.serializer())
|
||||
subclass(Extruded.serializer())
|
||||
subclass(Surface.serializer())
|
||||
subclass(PolyLine.serializer())
|
||||
subclass(SolidLabel.serializer())
|
||||
subclass(Sphere.serializer())
|
||||
|
@ -2,9 +2,14 @@ package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.dataforge.meta.MutableMeta
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.kmath.geometry.component1
|
||||
import space.kscience.kmath.geometry.component2
|
||||
import space.kscience.kmath.structures.Float32
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.setChild
|
||||
|
||||
|
||||
private inline fun <T> Iterable<T>.sumOf(selector: (T) -> Float32): Float32 {
|
||||
@ -130,7 +135,39 @@ public class Surface(
|
||||
}
|
||||
}
|
||||
|
||||
public class Builder(
|
||||
public var layers: MutableList<Layer> = ArrayList(),
|
||||
public val properties: MutableMeta = MutableMeta(),
|
||||
) {
|
||||
|
||||
public fun layer(
|
||||
z: Number,
|
||||
innerBuilder: (Shape2DBuilder.() -> Unit)? = null,
|
||||
outerBuilder: Shape2DBuilder.() -> Unit,
|
||||
) {
|
||||
layers.add(
|
||||
Layer(
|
||||
z.toFloat(),
|
||||
outer = Shape2DBuilder().apply(outerBuilder).build(),
|
||||
inner = innerBuilder?.let { Shape2DBuilder().apply(innerBuilder).build() }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
internal fun build(): Surface = Surface(layers).apply {
|
||||
properties.setMeta(Name.EMPTY, this@Builder.properties)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public companion object {
|
||||
public const val TYPE: String = "solid.surface"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@VisionBuilder
|
||||
public fun MutableVisionContainer<Solid>.surface(
|
||||
name: String? = null,
|
||||
action: Surface.Builder.() -> Unit = {},
|
||||
): Surface = Surface.Builder().apply(action).build().also { setChild(name, it) }
|
||||
|
Loading…
Reference in New Issue
Block a user