Reputation: 145
I make Wind direction enum and I want to make a range that catches all values between 2 numbers OR third one:
number between (0.0 and 45.0) OR (360.0)
enum class WindDirections(val description: String,val shortName : String, val range: ClosedFloatingPointRange<Double>,val image: Int) {
// North
NORTH("N North", "N" ,(0.0..45.0), R.drawable.wind_north_red50),
NORTH_EAST("NE North-East", "NE" ,45.1..90.0, R.drawable.wind_north_east_red),
(... East, South, West etc)
NOT_FOUND ("", "-",-1.1..-1.0,0); // error one, now 360* is inside that
(...)
With these functions, I want to get enum class - WindDirections with the right value, based on given angle windDirection: Double
. For example:
The angle between 0 and 45 (0.0..45.0) returns WindDirections.North (Now want to make when its 360 to return same)
The angle between 45.1 and 90 (45.1..90.0) returns WindDirections.NORTH_EAST
companion object {
fun getDescriptionStringByDouble(windDirection: Double): String {
return getWindDirectionByDouble(windDirection).description
}
fun getShortDescriptionStringByDouble(windDirection: Double):String {
return getWindDirectionByDouble(windDirection).shortName
}
I want to get North for a range of 0..45 and also 360
fun getWindDirectionByDouble(windDirection: Double): WindDirections {
return when (windDirection) {
in NORTH.range -> NORTH // number between (0.0 and 45.0) OR (360.0 need to accomplish that one, now it isn't)
in NORTH_EAST.range -> NORTH_EAST // 45 and 90
(... East, South, West etc)
else -> NOT_FOUND // when angle is not between 0 and 359.9 (for now 360 is here)
Thank you in advance
The way to accomplish that is to make when catching my special case for 360 in function getWindDirectionByDouble() like that in bellow, but I ask, is it possible to add 360 in the range of NORTH somehow. "(0.0..45.0) and (360.0)"
fun getWindDirectionByDouble(windDirection: Double): WindDirections {
return when (windDirection) {
360.0 -> NORTH // Like that one, i will return right WindDirections.NORTH
in NORTH.range -> NORTH // number between (0.0 and 45.0) OR (360.0 need to accomplish that one, now it isn't)
in NORTH_EAST.range -> NORTH_EAST // 45 and 90
(... East, South, West etc)
else -> NOT_FOUND
Upvotes: 0
Views: 680
Reputation: 93581
There is a flaw in using a Double ClosedRange for this since it treats the start and end inclusively. You worked around that by using 45.1 for example, but then there are numbers like 45.05 that won't be in any of the ranges.
You could make your own type of range that treats the end as exclusive. And you could also design it to handle angles outside 0-360 by calculating the positive remainder (modulo).
data class AngleRange(val start: Double, val endExclusive: Double) {
operator fun contains(value: Double) =
((value % 360.0 + 360.0) % 360.0).let { it >= start && it < endExclusive }
}
Then you can fully cover the possible ranges using AngleRange(0.0, 45.0)
, AngleRange(45.0, 90.0)
, etc.
Upvotes: 2