Vector
VectorPath, VectorBuilder, Shape2d, Shape2d union, difference, Triangulation, Vector Collision, Bezier...
KorMA provide several vectorial capabilities to generate all kind of vectorial shapes formed from lines, polygons and curves.
VectorPath and VectorBuilder
open class VectorPath(
val commands: IntArrayList = IntArrayList(),
val data: DoubleArrayList = DoubleArrayList(),
val winding: Winding = Winding.EVEN_ODD
) : VectorBuilder
interface VectorBuilder {
val totalPoints: Int
val lastX: Double
val lastY: Double
fun moveTo(x: Double, y: Double)
fun lineTo(x: Double, y: Double)
fun quadTo(cx: Double, cy: Double, ax: Double, ay: Double)
fun cubicTo(cx1: Double, cy1: Double, cx2: Double, cy2: Double, ax: Double, ay: Double)
fun close()
}
Constructing vectors with lines and curves
The basic classes for vector building are VectorPath
and VectorBuilder
.
They do not include color information, but just the vector shape.
You can make other classes to implement the VectorBuilder
interface by delegation to for example provide a Context2D-like interface with filling and stroking including all the extension methods provided.
Extension methods using the basic interface:
fun VectorBuilder.isEmpty(): Boolean
fun VectorBuilder.isNotEmpty(): Boolean
fun VectorBuilder.arcTo(ax: Double, ay: Double, cx: Double, cy: Double, r: Double)
fun VectorBuilder.rect(x: Double, y: Double, width: Double, height: Double)
fun VectorBuilder.rectHole(x: Double, y: Double, width: Double, height: Double)
fun VectorBuilder.roundRect(x: Double, y: Double, w: Double, h: Double, rx: Double, ry: Double = rx)
fun VectorBuilder.arc(x: Double, y: Double, r: Double, start: Double, end: Double)
fun VectorBuilder.circle(x: Double, y: Double, radius: Double)
fun VectorBuilder.ellipse(x: Double, y: Double, rw: Double, rh: Double)
fun VectorBuilder.moveTo(p: Point)
fun VectorBuilder.lineTo(p: Point)
fun VectorBuilder.quadTo(c: Point, a: Point)
fun VectorBuilder.cubicTo(c1: Point, c2: Point, a: Point)
inline fun VectorBuilder.moveTo(x: Number, y: Number)
inline fun VectorBuilder.lineTo(x: Number, y: Number)
inline fun VectorBuilder.quadTo(controlX: Number, controlY: Number, anchorX: Number, anchorY: Number)
inline fun VectorBuilder.cubicTo(cx1: Number, cy1: Number, cx2: Number, cy2: Number, ax: Number, ay: Number)
inline fun VectorBuilder.moveToH(x: Number)
inline fun VectorBuilder.rMoveToH(x: Number)
inline fun VectorBuilder.moveToV(y: Number)
inline fun VectorBuilder.rMoveToV(y: Number)
inline fun VectorBuilder.lineToH(x: Number)
inline fun VectorBuilder.rLineToH(x: Number)
inline fun VectorBuilder.lineToV(y: Number)
inline fun VectorBuilder.rLineToV(y: Number)
inline fun VectorBuilder.rMoveTo(x: Number, y: Number)
inline fun VectorBuilder.rLineTo(x: Number, y: Number)
inline fun VectorBuilder.rQuadTo(cx: Number, cy: Number, ax: Number, ay: Number)
inline fun VectorBuilder.rCubicTo(cx1: Number, cy1: Number, cx2: Number, cy2: Number, ax: Number, ay: Number)
inline fun VectorBuilder.arcTo(ax: Number, ay: Number, cx: Number, cy: Number, r: Number)
inline fun VectorBuilder.rect(x: Number, y: Number, width: Number, height: Number)
inline fun VectorBuilder.rectHole(x: Number, y: Number, width: Number, height: Number)
inline fun VectorBuilder.roundRect(x: Number, y: Number, w: Number, h: Number, rx: Number, ry: Number = rx)
inline fun VectorBuilder.arc(x: Number, y: Number, r: Number, start: Number, end: Number)
inline fun VectorBuilder.circle(x: Number, y: Number, radius: Number)
inline fun VectorBuilder.ellipse(x: Number, y: Number, rw: Number, rh: Number)
You can also determine if a point is contained inside a VectorPath
:
fun VectorPath.containsPoint(x: Double, y: Double): Boolean
Shape2d
Several algorithms require to work with simple straight segments. Korma provides a Shape2d set of classes to describe shapes.
You can convert a VectorPath
to a Shape2d
using the toShape2d
extension method:
val shape = VectorPath {
moveTo(0, 0)
lineTo(100, 0)
lineTo(100, 100)
close()
}.toShape2d()
Shape2d Operations
Intersection, Union, Xor, Difference, Collision Test, Growing/Shrinking
Korma provides a separate artifact called korma-shape-ops
that includes a Kotlin port of the Clipper
library integrated with the Shape2D
API.
It provides boolean methods to operate with two paths.
infix fun Shape2d.collidesWith(other: Shape2d): Boolean
infix fun Shape2d.intersection(other: Shape2d): Shape2d
infix fun Shape2d.union(other: Shape2d): Shape2d
infix fun Shape2d.xor(other: Shape2d): Shape2d
infix fun Shape2d.difference(other: Shape2d): Shape2d
operator fun Shape2d.plus(other: Shape2d): Shape2d
operator fun Shape2d.minus(other: Shape2d): Shape2d
fun Shape2d.extend(size: Double, cap: VectorPath.LineCap = VectorPath.LineCap.ROUND): Shape2d
fun Shape2d.extendLine(size: Double, join: VectorPath.LineJoin = VectorPath.LineJoin.SQUARE, cap: VectorPath.LineCap = VectorPath.LineCap.SQUARE): Shape2d
Triangulation
Shape2d: Triangulation and Triangulation-based Node and Point Path Finding
Korma provides a separate artifact called korma-triangulate-pathfind
to do triangulation and triangulation-based path finding.
Triangulating a set of polygons (or curves too after converting them into polygons with toShape2d
) has several use cases like drawing a vectorial shape into the GPU, doing physics or doing path finding.
To triangulate a set of points, a Shape2d
or a VectorPath
:
fun List<IPoint>.triangulate(): List<Triangle>
fun Shape2d.triangulate(): List<List<Triangle>>
fun Shape2d.triangulateFlat(): List<Triangle>
fun VectorPath.triangulate(): List<List<Triangle>>
fun VectorPath.triangulateFlat(): List<Triangle>
For pathfinding:
fun List<Triangle>.toSpatialMesh(): SpatialMesh
fun List<Triangle>.pathFind(): SpatialMeshFind
fun SpatialMeshFind.funnel(p0: IPoint, p1: IPoint): List<IPoint>
fun List<Triangle>.funnel(p0: IPoint, p1: IPoint): List<IPoint>
fun List<Triangle>.pathFind(p0: IPoint, p1: IPoint): List<IPoint>
fun Shape2d.toSpatialMesh(): SpatialMesh
fun Shape2d.pathFind(): SpatialMeshFind
fun Shape2d.pathFind(p0: IPoint, p1: IPoint): List<IPoint>
Additionally this library allows to compute the area of Shape2d by doing triangulation:
val Shape2d.area: Double
Extra: Bezier tools
Korma provides a Bezier
object with several methods to compute in a bezier curve (quadratic and cubic) their points, their length or their bounds.