Created
September 23, 2021 02:28
-
-
Save leontabak/342c4d54c2ffb8ab014d60476133b253 to your computer and use it in GitHub Desktop.
Cohen-Sutherland algorithm.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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