I hope the code says it all
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.math.Polar
import org.openrndr.shape.ShapeContour
/**
* Visualize segment left-turns and right-turns on a ShapeContour.
*/
fun main() = application {
program {
val pointCount = 16
// Create a ShapeContour out of points positioned using polar coordinates
// around the center of the screen.
val c = ShapeContour.fromPoints(
List(pointCount) {
val angle = it * 360.0 / pointCount
val radius = listOf(150.0, 200.0).random()
Polar(angle, radius).cartesian + drawer.bounds.center
}, closed = true
)
// Create a list of segments to work with. If the shape is closed, we need to add the first segment
// to the end of the list to be able to calculate the angle between the last segment and
// the first one
val segs = if(c.closed) c.segments + c.segments.first() else c.segments
// For each pair of segments, compare the normal at the end of the first segment with
// the direction at the start of the second segment. The dot product will be either positive
// or negative, telling us if it's convex or concave
val segData : List<Pair<Segment, Boolean>> =
segs.zipWithNext().map { (segA, segB) ->
segA to (segA.normal(1.0).dot(segB.direction(0.0)) > 0.0)
}
extend {
drawer.clear(ColorRGBa.WHITE)
drawer.fill = ColorRGBa.WHITE.shade(0.9)
drawer.contour(c)
// Visualize left-turns and right-turns in two different colors
segData.forEach { (seg, positive) ->
drawer.fill = if(positive) ColorRGBa.MAGENTA else ColorRGBa.CYAN
drawer.circle(seg.end, 10.0)
}
}
}
}