Skip to content

Instantly share code, notes, and snippets.

@leontabak
Created September 23, 2021 02:28
Show Gist options
  • Save leontabak/342c4d54c2ffb8ab014d60476133b253 to your computer and use it in GitHub Desktop.
Save leontabak/342c4d54c2ffb8ab014d60476133b253 to your computer and use it in GitHub Desktop.
Cohen-Sutherland algorithm.
/*
I wrote this code to introduce my students
to some features of the Kotlin language.
Leon Tabak
22 September 2021
*/
enum class ClippingStatus {
INSIDE,
OUTSIDE,
UNKNOWN
} // ClippingStatus
data class Point2D(
val x: Double,
val y: Double
) {
override fun toString(): String {
val xString = String.format("%6.2f", x)
val yString = String.format("%6.2f", y)
return "($xString, $yString)"
} // toString()
} // Point2D
data class LineSegment2D(
val head: Point2D,
val tail: Point2D
) {
override fun toString(): String {
return "($head, $tail)"
} // toString()
} // LineSegment2D
class Window(
private val xMin: Double,
private val xMax: Double,
private val yMin: Double,
private val yMax: Double
) {
val inside = mutableListOf<LineSegment2D>()
val outside = mutableListOf<LineSegment2D>()
val unknown = mutableListOf<LineSegment2D>()
fun addSegment(segment: LineSegment2D) {
fun classifyPoint(point: Point2D): Int {
val (x, y) = point
val west = if (x < xMin) 8 else 0
val east = if (x > xMax) 4 else 0
val south = if (y < yMin) 2 else 0
val north = if (y > yMax) 1 else 0
return east + west + south + north
} // classifyPoint( Point2D )
fun classifySegment(segment: LineSegment2D):
ClippingStatus {
val headCode = classifyPoint(segment.head)
val tailCode = classifyPoint(segment.tail)
return if (headCode or tailCode == 0)
ClippingStatus.INSIDE
else if (headCode and tailCode != 0)
ClippingStatus.OUTSIDE
else
ClippingStatus.UNKNOWN
} // classifySegment( LineSegment2D )
when (classifySegment(segment)) {
ClippingStatus.INSIDE -> inside.add(segment)
ClippingStatus.OUTSIDE -> outside.add(segment)
else -> unknown.add(segment)
} // when
} // addSegment()
} // Window
fun main() {
val rng = kotlin.random.Random(System.nanoTime())
val window = Window(
0.25, 0.75,
0.25, 0.75
)
for (i in 0 until 8) {
val p0 = Point2D(rng.nextDouble(), rng.nextDouble())
val p1 = Point2D(rng.nextDouble(), rng.nextDouble())
val segment = LineSegment2D(p0, p1)
window.addSegment(segment)
} // for
println("Segments inside the window:")
for (s in window.inside)
println(s)
println("Segments outside the window:")
for (s in window.outside)
println(s)
println("Segments whose status is unknown:")
for (s in window.unknown)
println(s)
} // main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment