diff --git a/android/build.gradle.kts b/android/build.gradle.kts index 2b625c84..0dd296d4 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -51,19 +51,10 @@ dependencies { implementation(libs.androidx.constraintlayout) implementation(libs.mapbox.maps) implementation(project(":math")) - implementation(project(":orx-triangulation")) { - exclude(group = "org.openrndr", module = "openrndr-draw") - } implementation(libs.androidx.lifecycle.runtime.ktx) implementation(project(":icegps-common")) implementation(project(":icegps-shared")) - implementation(project(":orx-marching-squares")) - implementation(project(":orx-palette")) { - exclude(group = "org.openrndr", module = "openrndr-draw") - } - implementation(project(":orx-shapes")) { - exclude(group = "org.openrndr", module = "openrndr-draw") - } + implementation(project(":icegps-triangulation")) testImplementation(libs.junit) androidTestImplementation(libs.ext.junit) diff --git a/android/src/main/java/com/icegps/orx/ContoursManager.kt b/android/src/main/java/com/icegps/orx/ContoursManager.kt index 4019713b..ba860cbc 100644 --- a/android/src/main/java/com/icegps/orx/ContoursManager.kt +++ b/android/src/main/java/com/icegps/orx/ContoursManager.kt @@ -4,14 +4,19 @@ import ColorBrewer2Type import android.content.Context import android.util.Log import colorBrewer2Palettes +import com.icegps.math.geometry.Rectangle +import com.icegps.math.geometry.Vector2D import com.icegps.math.geometry.Vector3D +import com.icegps.orx.catmullrom.CatmullRomChain2 import com.icegps.orx.ktx.area import com.icegps.orx.ktx.toColorInt import com.icegps.orx.ktx.toMapboxPoint import com.icegps.orx.ktx.toast -import com.icegps.orx.triangulation.DelaunayTriangulation3D -import com.icegps.orx.triangulation.Triangle3D +import com.icegps.orx.marchingsquares.ShapeContour +import com.icegps.orx.marchingsquares.findContours import com.icegps.shared.ktx.TAG +import com.icegps.triangulation.DelaunayTriangulation +import com.icegps.triangulation.Triangle import com.mapbox.geojson.Feature import com.mapbox.geojson.FeatureCollection import com.mapbox.geojson.LineString @@ -35,11 +40,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.openrndr.extra.shapes.splines.CatmullRomChain2 -import org.openrndr.math.Vector2 -import org.openrndr.math.Vector3 -import org.openrndr.shape.Rectangle -import org.openrndr.shape.ShapeContour import kotlin.math.max class ContoursManager( @@ -136,7 +136,7 @@ class ContoursManager( } } - private var triangles: List = listOf() + private var triangles: List = listOf() private var isTriangleVisible: Boolean = true fun setTriangleVisible(visible: Boolean) { @@ -170,10 +170,9 @@ class ContoursManager( val zip = (0..contourSize).map { index -> heightRange.start + index * step }.zipWithNext { a, b -> a..b } - val points = points.map { Vector3(it.x, it.y, it.z) } val area = points.area - val triangulation = DelaunayTriangulation3D(points) - val triangles: MutableList = triangulation.triangles() + val triangulation = DelaunayTriangulation(points) + val triangles = triangulation.triangles() val cellSize: Double = if (cellSize == null || cellSize!! < 0.1) { (max(triangulation.points.area.width, triangulation.points.area.height) / 50) } else { @@ -228,12 +227,12 @@ class ContoursManager( } fun findContours( - triangles: MutableList, + triangles: List, range: ClosedFloatingPointRange, area: Rectangle, cellSize: Double ): List { - return org.openrndr.extra.marchingsquares.findContours( + return findContours( f = { v -> val triangle = triangles.firstOrNull { triangle -> isPointInTriangle3D(v, listOf(triangle.x1, triangle.x2, triangle.x3)) @@ -370,7 +369,7 @@ class ContoursManager( } } -fun isPointInTriangle3D(point: Vector2, triangle: List): Boolean { +fun isPointInTriangle3D(point: Vector2D, triangle: List): Boolean { require(triangle.size == 3) { "三角形必须有3个顶点" } val (v1, v2, v3) = triangle @@ -395,15 +394,15 @@ fun isPointInTriangle3D(point: Vector2, triangle: List): Boolean { * @param triangle 三角形的三个顶点 * @return 三维点 (x, y, z) */ -fun interpolateHeight(point: Vector2, triangle: List): Vector3 { +fun interpolateHeight(point: Vector2D, triangle: List): Vector3D { /** * 计算点在三角形中的重心坐标 */ fun calculateBarycentricCoordinates( - point: Vector2, - v1: Vector3, - v2: Vector3, - v3: Vector3 + point: Vector2D, + v1: Vector3D, + v2: Vector3D, + v3: Vector3D ): Triple { val denom = (v2.y - v3.y) * (v1.x - v3.x) + (v3.x - v2.x) * (v1.y - v3.y) @@ -424,5 +423,5 @@ fun interpolateHeight(point: Vector2, triangle: List): Vector3 { // 使用重心坐标插值z值 val z = alpha * v1.z + beta * v2.z + gamma * v3.z - return Vector3(point.x, point.y, z) + return Vector3D(point.x, point.y, z) } diff --git a/android/src/main/java/com/icegps/orx/GridModel.kt b/android/src/main/java/com/icegps/orx/GridModel.kt index 538c6932..eae4e661 100644 --- a/android/src/main/java/com/icegps/orx/GridModel.kt +++ b/android/src/main/java/com/icegps/orx/GridModel.kt @@ -1,8 +1,8 @@ package com.icegps.orx import com.icegps.math.geometry.Vector2D -import com.icegps.orx.triangulation.DelaunayTriangulation3D -import org.openrndr.math.Vector3 +import com.icegps.math.geometry.Vector3D +import com.icegps.triangulation.DelaunayTriangulation import kotlin.math.absoluteValue import kotlin.math.ceil @@ -29,11 +29,11 @@ data class GridModel( } fun triangulationToGrid( - delaunator: DelaunayTriangulation3D, + delaunator: DelaunayTriangulation, cellSize: Double = 50.0, maxSidePixels: Int = 5000 ): GridModel { - fun pointInTriangle(pt: Vector2D, a: Vector3, b: Vector3, c: Vector3): Boolean { + fun pointInTriangle(pt: Vector2D, a: Vector3D, b: Vector3D, c: Vector3D): Boolean { val v0x = c.x - a.x val v0y = c.y - a.y val v1x = b.x - a.x @@ -55,11 +55,11 @@ fun triangulationToGrid( return u >= 0 && v >= 0 && u + v <= 1 } - fun barycentricInterpolateLegacy(pt: Vector2D, a: Vector3, b: Vector3, c: Vector3, values: DoubleArray): Double { - val area = { p1: Vector2D, p2: Vector3, p3: Vector3 -> + fun barycentricInterpolateLegacy(pt: Vector2D, a: Vector3D, b: Vector3D, c: Vector3D, values: DoubleArray): Double { + val area = { p1: Vector2D, p2: Vector3D, p3: Vector3D -> ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y)).absoluteValue / 2.0 } - val area2 = { p1: Vector3, p2: Vector3, p3: Vector3 -> + val area2 = { p1: Vector3D, p2: Vector3D, p3: Vector3D -> ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y)).absoluteValue / 2.0 } val areaTotal = area2(a, b, c) diff --git a/android/src/main/java/com/icegps/orx/PolylineManager.kt b/android/src/main/java/com/icegps/orx/PolylineManager.kt index aaad304b..ec1a2a0f 100644 --- a/android/src/main/java/com/icegps/orx/PolylineManager.kt +++ b/android/src/main/java/com/icegps/orx/PolylineManager.kt @@ -15,7 +15,6 @@ import com.mapbox.maps.extension.style.layers.properties.generated.LineCap import com.mapbox.maps.extension.style.layers.properties.generated.LineJoin import com.mapbox.maps.extension.style.sources.addSource import com.mapbox.maps.extension.style.sources.generated.geoJsonSource -import org.openrndr.math.YPolarity class PolylineManager( private val mapView: MapView @@ -99,7 +98,6 @@ class PolylineManager( fun fromPoints( points: List, closed: Boolean, - polarity: YPolarity = YPolarity.CW_NEGATIVE_Y ) = if (points.isEmpty()) { emptyList() } else { diff --git a/android/src/main/java/com/icegps/orx/catmullrom/CatmullRom.kt b/android/src/main/java/com/icegps/orx/catmullrom/CatmullRom.kt new file mode 100644 index 00000000..3a093f77 --- /dev/null +++ b/android/src/main/java/com/icegps/orx/catmullrom/CatmullRom.kt @@ -0,0 +1,135 @@ +package com.icegps.orx.catmullrom + +import com.icegps.math.geometry.Vector2D +import com.icegps.orx.marchingsquares.Segment2D +import com.icegps.orx.marchingsquares.ShapeContour +import kotlin.math.min +import kotlin.math.pow + +private const val almostZero = 0.00000001 +private const val almostOne = 0.99999999 + +/** + * Creates a 2D Catmull-Rom spline curve. + * + * Can be represented as a segment drawn between [p1] and [p2], + * while [p0] and [p3] are used as control points. + * + * Under some circumstances alpha can have + * no perceptible effect, for example, + * when creating closed shapes with the vertices + * forming a regular 2D polygon. + * + * @param p0 The first control point. + * @param p1 The starting anchor point. + * @param p2 The ending anchor point. + * @param p3 The second control point. + * @param alpha The *tension* of the curve. + * Use `0.0` for the uniform spline, `0.5` for the centripetal spline, `1.0` for the chordal spline. + */ +class CatmullRom2(val p0: Vector2D, val p1: Vector2D, val p2: Vector2D, val p3: Vector2D, val alpha: Double = 0.5) { + /** Value of t for p0. */ + val t0: Double = 0.0 + + /** Value of t for p1. */ + val t1: Double = calculateT(t0, p0, p1) + + /** Value of t for p2. */ + val t2: Double = calculateT(t1, p1, p2) + + /** Value of t for p3. */ + val t3: Double = calculateT(t2, p2, p3) + + fun position(rt: Double): Vector2D { + val t = t1 + rt * (t2 - t1) + val a1 = p0 * ((t1 - t) / (t1 - t0)) + p1 * ((t - t0) / (t1 - t0)) + val a2 = p1 * ((t2 - t) / (t2 - t1)) + p2 * ((t - t1) / (t2 - t1)) + val a3 = p2 * ((t3 - t) / (t3 - t2)) + p3 * ((t - t2) / (t3 - t2)) + + val b1 = a1 * ((t2 - t) / (t2 - t0)) + a2 * ((t - t0) / (t2 - t0)) + val b2 = a2 * ((t3 - t) / (t3 - t1)) + a3 * ((t - t1) / (t3 - t1)) + + val c = b1 * ((t2 - t) / (t2 - t1)) + b2 * ((t - t1) / (t2 - t1)) + return c + } + + private fun calculateT(t: Double, p0: Vector2D, p1: Vector2D): Double { + val a = (p1.x - p0.x).pow(2.0) + (p1.y - p0.y).pow(2.0) + val b = a.pow(0.5) + val c = b.pow(alpha) + return c + t + } +} + +/** + * Calculates the 2D Catmull–Rom spline for a chain of points and returns the combined curve. + * + * For more details, see [CatmullRom2]. + * + * @param points The [List] of 2D points where [CatmullRom2] is applied in groups of 4. + * @param alpha The *tension* of the curve. + * Use `0.0` for the uniform spline, `0.5` for the centripetal spline, `1.0` for the chordal spline. + * @param loop Whether to connect the first and last point, such that it forms a closed shape. + */ +class CatmullRomChain2(points: List, alpha: Double = 0.5, val loop: Boolean = false) { + val segments = if (!loop) { + val startPoints = points.take(2) + val endPoints = points.takeLast(2) + val mirrorStart = + startPoints.first() - (startPoints.last() - startPoints.first()).normalized + val mirrorEnd = endPoints.last() + (endPoints.last() - endPoints.first()).normalized + + (listOf(mirrorStart) + points + listOf(mirrorEnd)).windowed(4, 1).map { + CatmullRom2(it[0], it[1], it[2], it[3], alpha) + } + } else { + val cleanPoints = if (loop && points.first().distanceTo(points.last()) <= 1.0E-6) { + points.dropLast(1) + } else { + points + } + (cleanPoints + cleanPoints.take(3)).windowed(4, 1).map { + CatmullRom2(it[0], it[1], it[2], it[3], alpha) + } + } + + fun positions(steps: Int = segments.size * 4): List { + return (0..steps).map { + position(it.toDouble() / steps) + } + } + + fun position(rt: Double): Vector2D { + val st = if (loop) rt.mod(1.0) else rt.coerceIn(0.0, 1.0) + val segmentIndex = (min(almostOne, st) * segments.size).toInt() + val t = (min(almostOne, st) * segments.size) - segmentIndex + return segments[segmentIndex].position(t) + } +} + +fun List.catmullRom(alpha: Double = 0.5, closed: Boolean) = CatmullRomChain2(this, alpha, closed) + +/** Converts spline to a [Segment]. */ +fun CatmullRom2.toSegment(): Segment2D { + val d1a2 = (p1 - p0).length.pow(2 * alpha) + val d2a2 = (p2 - p1).length.pow(2 * alpha) + val d3a2 = (p3 - p2).length.pow(2 * alpha) + val d1a = (p1 - p0).length.pow(alpha) + val d2a = (p2 - p1).length.pow(alpha) + val d3a = (p3 - p2).length.pow(alpha) + + val b0 = p1 + val b1 = (p2 * d1a2 - p0 * d2a2 + p1 * (2 * d1a2 + 3 * d1a * d2a + d2a2)) / (3 * d1a * (d1a + d2a)) + val b2 = (p1 * d3a2 - p3 * d2a2 + p2 * (2 * d3a2 + 3 * d3a * d2a + d2a2)) / (3 * d3a * (d3a + d2a)) + val b3 = p2 + + return Segment2D(b0, b1, b2, b3) +} + + +/** + * Converts chain to a [ShapeContour]. + */ +@Suppress("unused") +fun CatmullRomChain2.toContour(): ShapeContour = + ShapeContour(segments.map { it.toSegment() }, this.loop) diff --git a/android/src/main/java/com/icegps/orx/color/ColorRGBa.kt b/android/src/main/java/com/icegps/orx/color/ColorRGBa.kt new file mode 100644 index 00000000..cd53a619 --- /dev/null +++ b/android/src/main/java/com/icegps/orx/color/ColorRGBa.kt @@ -0,0 +1,427 @@ +package com.icegps.orx.color + +import com.icegps.math.geometry.Vector3D +import com.icegps.math.geometry.Vector4D +import kotlinx.serialization.Serializable +import kotlin.math.pow + +@Serializable +enum class Linearity(val certainty: Int) { + /** + * Represents a linear color space. + * + * LINEAR typically signifies that the values in the color space are in a linear relationship, + * meaning there is no gamma correction or transformation applied to the data. + */ + LINEAR(1), + + /** + * Represents a standard RGB (sRGB) color space. + * + * SRGB typically refers to a non-linear color space with gamma correction applied, + * designed for consistent color representation across devices. + */ + SRGB(1), + ; + + fun leastCertain(other: Linearity): Linearity { + return if (this.certainty <= other.certainty) { + this + } else { + other + } + } + + fun isEquivalent(other: Linearity): Boolean { + return this == other + } + +} + +/** + * Represents a color in the RGBA color space. Each component, including red, green, blue, and alpha (opacity), + * is represented as a `Double` in the range `[0.0, 1.0]`. The color can be defined in either linear or sRGB space, + * determined by the `linearity` property. + * + * This class provides a wide variety of utility functions for manipulating and converting colors, such as shading, + * opacity adjustment, and format transformations. It also includes methods for parsing colors from hexadecimal + * notation or vectors. + * + * @property r Red component of the color as a value between `0.0` and `1.0`. + * @property g Green component of the color as a value between `0.0` and `1.0`. + * @property b Blue component of the color as a value between `0.0` and `1.0`. + * @property alpha Alpha (opacity) component of the color as a value between `0.0` and `1.0`. Defaults to `1.0`. + * @property linearity Indicates whether the color is defined in linear or sRGB space. Defaults to [Linearity.LINEAR]. + */ +@Serializable +@Suppress("EqualsOrHashCode") // generated equals() is ok, only hashCode() needs to be overridden +data class ColorRGBa( + val r: Double, + val g: Double, + val b: Double, + val alpha: Double = 1.0, + val linearity: Linearity = Linearity.LINEAR +) { + + enum class Component { + R, + G, + B + } + + companion object { + /** + * Calculates a color from hexadecimal value. For values with transparency + * use the [String] variant of this function. + */ + fun fromHex(hex: Int): ColorRGBa { + val r = hex and (0xff0000) shr 16 + val g = hex and (0x00ff00) shr 8 + val b = hex and (0x0000ff) + return ColorRGBa(r / 255.0, g / 255.0, b / 255.0, 1.0, Linearity.SRGB) + } + + /** + * Calculates a color from hexadecimal notation, like in CSS. + * + * Supports the following formats + * * `RGB` + * * `RGBA` + * * `RRGGBB` + * * `RRGGBBAA` + * + * where every character is a valid hex digit between `0..f` (case-insensitive). + * Supports leading "#" or "0x". + */ + fun fromHex(hex: String): ColorRGBa { + val pos = when { + hex.startsWith("#") -> 1 + hex.startsWith("0x") -> 2 + else -> 0 + } + + fun fromHex1(str: String, pos: Int): Double { + return 17 * str[pos].digitToInt(16) / 255.0 + } + + fun fromHex2(str: String, pos: Int): Double { + return (16 * str[pos].digitToInt(16) + str[pos + 1].digitToInt(16)) / 255.0 + } + return when (hex.length - pos) { + 3 -> ColorRGBa(fromHex1(hex, pos), fromHex1(hex, pos + 1), fromHex1(hex, pos + 2), 1.0, Linearity.SRGB) + 4 -> ColorRGBa( + fromHex1(hex, pos), + fromHex1(hex, pos + 1), + fromHex1(hex, pos + 2), + fromHex1(hex, pos + 3), + Linearity.SRGB + ) + + 6 -> ColorRGBa(fromHex2(hex, pos), fromHex2(hex, pos + 2), fromHex2(hex, pos + 4), 1.0, Linearity.SRGB) + 8 -> ColorRGBa( + fromHex2(hex, pos), + fromHex2(hex, pos + 2), + fromHex2(hex, pos + 4), + fromHex2(hex, pos + 6), + Linearity.SRGB + ) + + else -> throw IllegalArgumentException("Invalid hex length/format for '$hex'") + } + } + + /** @suppress */ + val PINK = fromHex(0xffc0cb) + + /** @suppress */ + val BLACK = ColorRGBa(0.0, 0.0, 0.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val WHITE = ColorRGBa(1.0, 1.0, 1.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val RED = ColorRGBa(1.0, 0.0, 0.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val BLUE = ColorRGBa(0.0, 0.0, 1.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val GREEN = ColorRGBa(0.0, 1.0, 0.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val YELLOW = ColorRGBa(1.0, 1.0, 0.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val CYAN = ColorRGBa(0.0, 1.0, 1.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val MAGENTA = ColorRGBa(1.0, 0.0, 1.0, 1.0, Linearity.SRGB) + + /** @suppress */ + val GRAY = ColorRGBa(0.5, 0.5, 0.5, 1.0, Linearity.SRGB) + + /** @suppress */ + val TRANSPARENT = ColorRGBa(0.0, 0.0, 0.0, 0.0, Linearity.LINEAR) + + /** + * Create a ColorRGBa object from a [Vector3] + * @param vector input vector, `[x, y, z]` is mapped to `[r, g, b]` + * @param alpha optional alpha value, default is 1.0 + */ + fun fromVector(vector: Vector3D, alpha: Double = 1.0, linearity: Linearity = Linearity.LINEAR): ColorRGBa { + return ColorRGBa(vector.x, vector.y, vector.z, alpha, linearity) + } + + + /** + * Create a ColorRGBa object from a [Vector4] + * @param vector input vector, `[x, y, z, w]` is mapped to `[r, g, b, a]` + */ + fun fromVector(vector: Vector4D, linearity: Linearity = Linearity.LINEAR): ColorRGBa { + return ColorRGBa(vector.x, vector.y, vector.z, vector.w, linearity) + } + } + + @Deprecated("Legacy alpha parameter name", ReplaceWith("alpha")) + val a = alpha + + /** + * Creates a copy of color with adjusted opacity + * @param factor a scaling factor used for the opacity + * @return A [ColorRGBa] with scaled opacity + * @see shade + */ + fun opacify(factor: Double): ColorRGBa = ColorRGBa(r, g, b, alpha * factor, linearity) + + /** + * Creates a copy of color with adjusted color + * @param factor a scaling factor used for the opacity + * @return A [ColorRGBa] with scaled colors + * @see opacify + */ + fun shade(factor: Double): ColorRGBa = ColorRGBa(r * factor, g * factor, b * factor, alpha, linearity) + + /** + * Copy of the color with all of its fields clamped to `[0, 1]` + */ + + @Deprecated("Use clip() instead", replaceWith = ReplaceWith("clip()")) + val saturated: ColorRGBa + get() = clip() + + /** + * Copy of the color with all of its fields clamped to `[0, 1]` + */ + fun clip(): ColorRGBa = copy( + r = r.coerceIn(0.0..1.0), + g = g.coerceIn(0.0..1.0), + b = b.coerceIn(0.0..1.0), + alpha = alpha.coerceIn(0.0..1.0) + ) + + + /** + * Returns a new instance of [ColorRGBa] where the red, green, and blue components + * are multiplied by the alpha value of the original color. The alpha value and linearity + * remain unchanged. + * + * This computed property is commonly used for adjusting the color intensity based + * on its transparency. + */ + val alphaMultiplied: ColorRGBa + get() = ColorRGBa(r * alpha, g * alpha, b * alpha, alpha, linearity) + + /** + * The minimum value over `r`, `g`, `b` + * @see maxValue + */ + val minValue get() = r.coerceAtMost(g).coerceAtMost(b) + + /** + * The maximum value over `r`, `g`, `b` + * @see minValue + */ + val maxValue get() = r.coerceAtLeast(g).coerceAtLeast(b) + + /** + * calculate luminance value + * luminance value is according to https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef + */ + val luminance: Double + get() = when (linearity) { + Linearity.SRGB -> toLinear().luminance + else -> 0.2126 * r + 0.7152 * g + 0.0722 * b + } + + /** + * Converts this color to the specified linearity. + * + * @param linearity The target linearity to which the color should be converted. + * Supported values are [Linearity.SRGB] and [Linearity.LINEAR]. + * @return A [ColorRGBa] instance in the specified linearity. + */ + fun toLinearity(linearity: Linearity): ColorRGBa { + return when (linearity) { + Linearity.SRGB -> toSRGB() + Linearity.LINEAR -> toLinear() + } + } + + /** + * calculate the contrast value between this color and the given color + * contrast value is accordingo to // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef + */ + fun getContrastRatio(other: ColorRGBa): Double { + val l1 = luminance + val l2 = other.luminance + return if (l1 > l2) (l1 + 0.05) / (l2 + 0.05) else (l2 + 0.05) / (l1 + 0.05) + } + + fun toLinear(): ColorRGBa { + fun t(x: Double): Double { + return if (x <= 0.04045) x / 12.92 else ((x + 0.055) / (1 + 0.055)).pow(2.4) + } + return when (linearity) { + Linearity.SRGB -> ColorRGBa(t(r), t(g), t(b), alpha, Linearity.LINEAR) + else -> this + } + } + + /** + * Convert to SRGB + * @see toLinear + */ + fun toSRGB(): ColorRGBa { + fun t(x: Double): Double { + return if (x <= 0.0031308) 12.92 * x else (1 + 0.055) * x.pow(1.0 / 2.4) - 0.055 + } + return when (linearity) { + Linearity.LINEAR -> ColorRGBa(t(r), t(g), t(b), alpha, Linearity.SRGB) + else -> this + } + } + + fun toRGBa(): ColorRGBa = this + + // This is here because the default hashing of enums on the JVM is not stable. + override fun hashCode(): Int { + var result = r.hashCode() + result = 31 * result + g.hashCode() + result = 31 * result + b.hashCode() + result = 31 * result + alpha.hashCode() + // here we overcome the unstable hash by using the ordinal value + result = 31 * result + linearity.ordinal.hashCode() + return result + } + + fun plus(right: ColorRGBa) = copy( + r = r + right.r, + g = g + right.g, + b = b + right.b, + alpha = alpha + right.alpha + ) + + fun minus(right: ColorRGBa) = copy( + r = r - right.r, + g = g - right.g, + b = b - right.b, + alpha = alpha - right.alpha + ) + + fun times(scale: Double) = copy(r = r * scale, g = g * scale, b = b * scale, alpha = alpha * scale) + + fun mix(other: ColorRGBa, factor: Double): ColorRGBa { + return mix(this, other, factor) + } + + fun toVector4(): Vector4D = Vector4D(r, g, b, alpha) + + /** + * Retrieves the color's RGBA component value based on the specified index: + * [index] should be 0 for red, 1 for green, 2 for blue, 3 for alpha. + * Other index values throw an [IndexOutOfBoundsException]. + */ + operator fun get(index: Int) = when (index) { + 0 -> r + 1 -> g + 2 -> b + 3 -> alpha + else -> throw IllegalArgumentException("unsupported index") + } +} + +/** + * Weighted mix between two colors in the generic RGB color space. + * @param x the weighting of colors, a value 0.0 is equivalent to [left], + * 1.0 is equivalent to [right] and at 0.5 both colors contribute to the result equally + * @return a mix of [left] and [right] weighted by [x] + */ +fun mix(left: ColorRGBa, right: ColorRGBa, x: Double): ColorRGBa { + val sx = x.coerceIn(0.0, 1.0) + + if (left.linearity.isEquivalent(right.linearity)) { + return ColorRGBa( + (1.0 - sx) * left.r + sx * right.r, + (1.0 - sx) * left.g + sx * right.g, + (1.0 - sx) * left.b + sx * right.b, + (1.0 - sx) * left.alpha + sx * right.alpha, + linearity = left.linearity.leastCertain(right.linearity) + ) + } else { + return when (right.linearity) { + Linearity.LINEAR -> { + mix(left.toLinear(), right.toLinear(), x) + } + + Linearity.SRGB -> { + mix(left.toSRGB(), right.toSRGB(), x) + } + } + } +} + +/** + * Shorthand for calling [ColorRGBa]. + * Specify only one value to obtain a shade of gray. + * @param r red in `[0,1]` + * @param g green in `[0,1]` + * @param b blue in `[0,1]` + * @param a alpha in `[0,1]`, defaults to `1.0` + */ +fun rgb(r: Double, g: Double, b: Double, a: Double = 1.0) = ColorRGBa(r, g, b, a, linearity = Linearity.LINEAR) + +/** + * Shorthand for calling [ColorRGBa]. + * @param gray shade of gray in `[0,1]` + * @param a alpha in `[0,1]`, defaults to `1.0` + */ +fun rgb(gray: Double, a: Double = 1.0) = ColorRGBa(gray, gray, gray, a, linearity = Linearity.LINEAR) + +/** + * Create a color in RGBa space + * This function is a shorthand for using the ColorRGBa constructor + * @param r red in `[0,1]` + * @param g green in `[0,1]` + * @param b blue in `[0,1]` + * @param a alpha in `[0,1]` + */ +@Deprecated("Use rgb(r, g, b, a)", ReplaceWith("rgb(r, g, b, a)"), DeprecationLevel.WARNING) +fun rgba(r: Double, g: Double, b: Double, a: Double) = ColorRGBa(r, g, b, a, linearity = Linearity.LINEAR) + +/** + * Shorthand for calling [ColorRGBa.fromHex]. + * Creates a [ColorRGBa] with [Linearity.SRGB] from a hex string. + * @param hex string encoded hex value, for example `"ffc0cd"` + */ +fun rgb(hex: String) = ColorRGBa.fromHex(hex) + +/** + * Converts RGB integer color values into a ColorRGBa object with sRGB linearity. + * + * @param red The red component of the color, in the range 0-255. + * @param green The green component of the color, in the range 0-255. + * @param blue The blue component of the color, in the range 0-255. + * @param alpha The alpha (transparency) component of the color, in the range 0-255. Default value is 255 (fully opaque). + */ +fun rgb(red: Int, green: Int, blue: Int, alpha: Int = 255) = + ColorRGBa(red / 255.0, green / 255.0, blue / 255.0, alpha / 255.0, Linearity.SRGB) diff --git a/android/src/main/java/com/icegps/orx/colorbrewer2/ColorBrewer2.kt b/android/src/main/java/com/icegps/orx/colorbrewer2/ColorBrewer2.kt new file mode 100644 index 00000000..72881db9 --- /dev/null +++ b/android/src/main/java/com/icegps/orx/colorbrewer2/ColorBrewer2.kt @@ -0,0 +1,2777 @@ +import com.icegps.orx.color.ColorRGBa +import com.icegps.orx.color.rgb + +/** + * # ColorBrewer2 + * + * https://colorbrewer2.org/ + * + * Based on the research of Dr. Cynthia Brewer. + */ + +enum class ColorBrewer2Type { + Any, Diverging, Qualitative, Sequential +} + +class ColorBrewer2Palette(val colors: List, val type: ColorBrewer2Type) + +val colorBrewer2 = listOf( + ColorBrewer2Palette( + listOf( + rgb(0.9882, 0.5529, 0.3490), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.6000, 0.8353, 0.5804) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.0980, 0.1098), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.6706, 0.8667, 0.6431), + rgb(0.1686, 0.5137, 0.7294) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.0980, 0.1098), + rgb(0.9922, 0.6824, 0.3804), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.6706, 0.8667, 0.6431), + rgb(0.1686, 0.5137, 0.7294) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8353, 0.2431, 0.3098), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9961, 0.8784, 0.5451), + rgb(0.9020, 0.9608, 0.5961), + rgb(0.6000, 0.8353, 0.5804), + rgb(0.1961, 0.5333, 0.7412) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8353, 0.2431, 0.3098), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9961, 0.8784, 0.5451), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.9020, 0.9608, 0.5961), + rgb(0.6000, 0.8353, 0.5804), + rgb(0.1961, 0.5333, 0.7412) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8353, 0.2431, 0.3098), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(0.9020, 0.9608, 0.5961), + rgb(0.6706, 0.8667, 0.6431), + rgb(0.4000, 0.7608, 0.6471), + rgb(0.1961, 0.5333, 0.7412) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8353, 0.2431, 0.3098), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.9020, 0.9608, 0.5961), + rgb(0.6706, 0.8667, 0.6431), + rgb(0.4000, 0.7608, 0.6471), + rgb(0.1961, 0.5333, 0.7412) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6196, 0.0039, 0.2588), + rgb(0.8353, 0.2431, 0.3098), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(0.9020, 0.9608, 0.5961), + rgb(0.6706, 0.8667, 0.6431), + rgb(0.4000, 0.7608, 0.6471), + rgb(0.1961, 0.5333, 0.7412), + rgb(0.3686, 0.3098, 0.6353) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6196, 0.0039, 0.2588), + rgb(0.8353, 0.2431, 0.3098), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.9020, 0.9608, 0.5961), + rgb(0.6706, 0.8667, 0.6431), + rgb(0.4000, 0.7608, 0.6471), + rgb(0.1961, 0.5333, 0.7412), + rgb(0.3686, 0.3098, 0.6353) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9882, 0.5529, 0.3490), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.5686, 0.8118, 0.3765) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.0980, 0.1098), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.6510, 0.8510, 0.4157), + rgb(0.1020, 0.5882, 0.2549) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.0980, 0.1098), + rgb(0.9922, 0.6824, 0.3804), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.6510, 0.8510, 0.4157), + rgb(0.1020, 0.5882, 0.2549) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9961, 0.8784, 0.5451), + rgb(0.8510, 0.9373, 0.5451), + rgb(0.5686, 0.8118, 0.3765), + rgb(0.1020, 0.5961, 0.3137) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9961, 0.8784, 0.5451), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.8510, 0.9373, 0.5451), + rgb(0.5686, 0.8118, 0.3765), + rgb(0.1020, 0.5961, 0.3137) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(0.8510, 0.9373, 0.5451), + rgb(0.6510, 0.8510, 0.4157), + rgb(0.4000, 0.7412, 0.3882), + rgb(0.1020, 0.5961, 0.3137) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.8510, 0.9373, 0.5451), + rgb(0.6510, 0.8510, 0.4157), + rgb(0.4000, 0.7412, 0.3882), + rgb(0.1020, 0.5961, 0.3137) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6471, 0.0000, 0.1490), + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(0.8510, 0.9373, 0.5451), + rgb(0.6510, 0.8510, 0.4157), + rgb(0.4000, 0.7412, 0.3882), + rgb(0.1020, 0.5961, 0.3137), + rgb(0.0000, 0.4078, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6471, 0.0000, 0.1490), + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5451), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.8510, 0.9373, 0.5451), + rgb(0.6510, 0.8510, 0.4157), + rgb(0.4000, 0.7412, 0.3882), + rgb(0.1020, 0.5961, 0.3137), + rgb(0.0000, 0.4078, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9373, 0.5412, 0.3843), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.4039, 0.6627, 0.8118) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7922, 0.0000, 0.1255), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.5725, 0.7725, 0.8706), + rgb(0.0196, 0.4431, 0.6902) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7922, 0.0000, 0.1255), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.5725, 0.7725, 0.8706), + rgb(0.0196, 0.4431, 0.6902) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.9373, 0.5412, 0.3843), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.8196, 0.8980, 0.9412), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.1294, 0.4000, 0.6745) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.9373, 0.5412, 0.3843), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8196, 0.8980, 0.9412), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.1294, 0.4000, 0.6745) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.8196, 0.8980, 0.9412), + rgb(0.5725, 0.7725, 0.8706), + rgb(0.2627, 0.5765, 0.7647), + rgb(0.1294, 0.4000, 0.6745) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8196, 0.8980, 0.9412), + rgb(0.5725, 0.7725, 0.8706), + rgb(0.2627, 0.5765, 0.7647), + rgb(0.1294, 0.4000, 0.6745) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4039, 0.0000, 0.1216), + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.8196, 0.8980, 0.9412), + rgb(0.5725, 0.7725, 0.8706), + rgb(0.2627, 0.5765, 0.7647), + rgb(0.1294, 0.4000, 0.6745), + rgb(0.0196, 0.1882, 0.3804) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4039, 0.0000, 0.1216), + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8196, 0.8980, 0.9412), + rgb(0.5725, 0.7725, 0.8706), + rgb(0.2627, 0.5765, 0.7647), + rgb(0.1294, 0.4000, 0.6745), + rgb(0.0196, 0.1882, 0.3804) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9137, 0.6392, 0.7882), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.6314, 0.8431, 0.4157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8157, 0.1098, 0.5451), + rgb(0.9451, 0.7137, 0.8549), + rgb(0.7216, 0.8824, 0.5255), + rgb(0.3020, 0.6745, 0.1490) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8157, 0.1098, 0.5451), + rgb(0.9451, 0.7137, 0.8549), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.7216, 0.8824, 0.5255), + rgb(0.3020, 0.6745, 0.1490) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7725, 0.1059, 0.4902), + rgb(0.9137, 0.6392, 0.7882), + rgb(0.9922, 0.8784, 0.9373), + rgb(0.9020, 0.9608, 0.8157), + rgb(0.6314, 0.8431, 0.4157), + rgb(0.3020, 0.5725, 0.1294) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7725, 0.1059, 0.4902), + rgb(0.9137, 0.6392, 0.7882), + rgb(0.9922, 0.8784, 0.9373), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.9020, 0.9608, 0.8157), + rgb(0.6314, 0.8431, 0.4157), + rgb(0.3020, 0.5725, 0.1294) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7725, 0.1059, 0.4902), + rgb(0.8706, 0.4667, 0.6824), + rgb(0.9451, 0.7137, 0.8549), + rgb(0.9922, 0.8784, 0.9373), + rgb(0.9020, 0.9608, 0.8157), + rgb(0.7216, 0.8824, 0.5255), + rgb(0.4980, 0.7373, 0.2549), + rgb(0.3020, 0.5725, 0.1294) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7725, 0.1059, 0.4902), + rgb(0.8706, 0.4667, 0.6824), + rgb(0.9451, 0.7137, 0.8549), + rgb(0.9922, 0.8784, 0.9373), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.9020, 0.9608, 0.8157), + rgb(0.7216, 0.8824, 0.5255), + rgb(0.4980, 0.7373, 0.2549), + rgb(0.3020, 0.5725, 0.1294) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.5569, 0.0039, 0.3216), + rgb(0.7725, 0.1059, 0.4902), + rgb(0.8706, 0.4667, 0.6824), + rgb(0.9451, 0.7137, 0.8549), + rgb(0.9922, 0.8784, 0.9373), + rgb(0.9020, 0.9608, 0.8157), + rgb(0.7216, 0.8824, 0.5255), + rgb(0.4980, 0.7373, 0.2549), + rgb(0.3020, 0.5725, 0.1294), + rgb(0.1529, 0.3922, 0.0980) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.5569, 0.0039, 0.3216), + rgb(0.7725, 0.1059, 0.4902), + rgb(0.8706, 0.4667, 0.6824), + rgb(0.9451, 0.7137, 0.8549), + rgb(0.9922, 0.8784, 0.9373), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.9020, 0.9608, 0.8157), + rgb(0.7216, 0.8824, 0.5255), + rgb(0.4980, 0.7373, 0.2549), + rgb(0.3020, 0.5725, 0.1294), + rgb(0.1529, 0.3922, 0.0980) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6863, 0.5529, 0.7647), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.4980, 0.7490, 0.4824) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4824, 0.1961, 0.5804), + rgb(0.7608, 0.6471, 0.8118), + rgb(0.6510, 0.8588, 0.6275), + rgb(0.0000, 0.5333, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4824, 0.1961, 0.5804), + rgb(0.7608, 0.6471, 0.8118), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.6510, 0.8588, 0.6275), + rgb(0.0000, 0.5333, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4627, 0.1647, 0.5137), + rgb(0.6863, 0.5529, 0.7647), + rgb(0.9059, 0.8314, 0.9098), + rgb(0.8510, 0.9412, 0.8275), + rgb(0.4980, 0.7490, 0.4824), + rgb(0.1059, 0.4706, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4627, 0.1647, 0.5137), + rgb(0.6863, 0.5529, 0.7647), + rgb(0.9059, 0.8314, 0.9098), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8510, 0.9412, 0.8275), + rgb(0.4980, 0.7490, 0.4824), + rgb(0.1059, 0.4706, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4627, 0.1647, 0.5137), + rgb(0.6000, 0.4392, 0.6706), + rgb(0.7608, 0.6471, 0.8118), + rgb(0.9059, 0.8314, 0.9098), + rgb(0.8510, 0.9412, 0.8275), + rgb(0.6510, 0.8588, 0.6275), + rgb(0.3529, 0.6824, 0.3804), + rgb(0.1059, 0.4706, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4627, 0.1647, 0.5137), + rgb(0.6000, 0.4392, 0.6706), + rgb(0.7608, 0.6471, 0.8118), + rgb(0.9059, 0.8314, 0.9098), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8510, 0.9412, 0.8275), + rgb(0.6510, 0.8588, 0.6275), + rgb(0.3529, 0.6824, 0.3804), + rgb(0.1059, 0.4706, 0.2157) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.2510, 0.0000, 0.2941), + rgb(0.4627, 0.1647, 0.5137), + rgb(0.6000, 0.4392, 0.6706), + rgb(0.7608, 0.6471, 0.8118), + rgb(0.9059, 0.8314, 0.9098), + rgb(0.8510, 0.9412, 0.8275), + rgb(0.6510, 0.8588, 0.6275), + rgb(0.3529, 0.6824, 0.3804), + rgb(0.1059, 0.4706, 0.2157), + rgb(0.0000, 0.2667, 0.1059) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.2510, 0.0000, 0.2941), + rgb(0.4627, 0.1647, 0.5137), + rgb(0.6000, 0.4392, 0.6706), + rgb(0.7608, 0.6471, 0.8118), + rgb(0.9059, 0.8314, 0.9098), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8510, 0.9412, 0.8275), + rgb(0.6510, 0.8588, 0.6275), + rgb(0.3529, 0.6824, 0.3804), + rgb(0.1059, 0.4706, 0.2157), + rgb(0.0000, 0.2667, 0.1059) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9882, 0.5529, 0.3490), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.5686, 0.7490, 0.8588) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.0980, 0.1098), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.6706, 0.8510, 0.9137), + rgb(0.1725, 0.4824, 0.7137) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.0980, 0.1098), + rgb(0.9922, 0.6824, 0.3804), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.6706, 0.8510, 0.9137), + rgb(0.1725, 0.4824, 0.7137) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9961, 0.8784, 0.5647), + rgb(0.8784, 0.9529, 0.9725), + rgb(0.5686, 0.7490, 0.8588), + rgb(0.2706, 0.4588, 0.7059) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9961, 0.8784, 0.5647), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.8784, 0.9529, 0.9725), + rgb(0.5686, 0.7490, 0.8588), + rgb(0.2706, 0.4588, 0.7059) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5647), + rgb(0.8784, 0.9529, 0.9725), + rgb(0.6706, 0.8510, 0.9137), + rgb(0.4549, 0.6784, 0.8196), + rgb(0.2706, 0.4588, 0.7059) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5647), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.8784, 0.9529, 0.9725), + rgb(0.6706, 0.8510, 0.9137), + rgb(0.4549, 0.6784, 0.8196), + rgb(0.2706, 0.4588, 0.7059) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6471, 0.0000, 0.1490), + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5647), + rgb(0.8784, 0.9529, 0.9725), + rgb(0.6706, 0.8510, 0.9137), + rgb(0.4549, 0.6784, 0.8196), + rgb(0.2706, 0.4588, 0.7059), + rgb(0.1922, 0.2118, 0.5843) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6471, 0.0000, 0.1490), + rgb(0.8431, 0.1882, 0.1529), + rgb(0.9569, 0.4275, 0.2627), + rgb(0.9922, 0.6824, 0.3804), + rgb(0.9961, 0.8784, 0.5647), + rgb(1.0000, 1.0000, 0.7490), + rgb(0.8784, 0.9529, 0.9725), + rgb(0.6706, 0.8510, 0.9137), + rgb(0.4549, 0.6784, 0.8196), + rgb(0.2706, 0.4588, 0.7059), + rgb(0.1922, 0.2118, 0.5843) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.8471, 0.7020, 0.3961), + rgb(0.9608, 0.9608, 0.9608), + rgb(0.3529, 0.7059, 0.6745) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.3804, 0.1020), + rgb(0.8745, 0.7608, 0.4902), + rgb(0.5020, 0.8039, 0.7569), + rgb(0.0039, 0.5216, 0.4431) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.3804, 0.1020), + rgb(0.8745, 0.7608, 0.4902), + rgb(0.9608, 0.9608, 0.9608), + rgb(0.5020, 0.8039, 0.7569), + rgb(0.0039, 0.5216, 0.4431) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.5490, 0.3176, 0.0392), + rgb(0.8471, 0.7020, 0.3961), + rgb(0.9647, 0.9098, 0.7647), + rgb(0.7804, 0.9176, 0.8980), + rgb(0.3529, 0.7059, 0.6745), + rgb(0.0039, 0.4000, 0.3686) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.5490, 0.3176, 0.0392), + rgb(0.8471, 0.7020, 0.3961), + rgb(0.9647, 0.9098, 0.7647), + rgb(0.9608, 0.9608, 0.9608), + rgb(0.7804, 0.9176, 0.8980), + rgb(0.3529, 0.7059, 0.6745), + rgb(0.0039, 0.4000, 0.3686) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.5490, 0.3176, 0.0392), + rgb(0.7490, 0.5059, 0.1765), + rgb(0.8745, 0.7608, 0.4902), + rgb(0.9647, 0.9098, 0.7647), + rgb(0.7804, 0.9176, 0.8980), + rgb(0.5020, 0.8039, 0.7569), + rgb(0.2078, 0.5922, 0.5608), + rgb(0.0039, 0.4000, 0.3686) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.5490, 0.3176, 0.0392), + rgb(0.7490, 0.5059, 0.1765), + rgb(0.8745, 0.7608, 0.4902), + rgb(0.9647, 0.9098, 0.7647), + rgb(0.9608, 0.9608, 0.9608), + rgb(0.7804, 0.9176, 0.8980), + rgb(0.5020, 0.8039, 0.7569), + rgb(0.2078, 0.5922, 0.5608), + rgb(0.0039, 0.4000, 0.3686) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.3294, 0.1882, 0.0196), + rgb(0.5490, 0.3176, 0.0392), + rgb(0.7490, 0.5059, 0.1765), + rgb(0.8745, 0.7608, 0.4902), + rgb(0.9647, 0.9098, 0.7647), + rgb(0.7804, 0.9176, 0.8980), + rgb(0.5020, 0.8039, 0.7569), + rgb(0.2078, 0.5922, 0.5608), + rgb(0.0039, 0.4000, 0.3686), + rgb(0.0000, 0.2353, 0.1882) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.3294, 0.1882, 0.0196), + rgb(0.5490, 0.3176, 0.0392), + rgb(0.7490, 0.5059, 0.1765), + rgb(0.8745, 0.7608, 0.4902), + rgb(0.9647, 0.9098, 0.7647), + rgb(0.9608, 0.9608, 0.9608), + rgb(0.7804, 0.9176, 0.8980), + rgb(0.5020, 0.8039, 0.7569), + rgb(0.2078, 0.5922, 0.5608), + rgb(0.0039, 0.4000, 0.3686), + rgb(0.0000, 0.2353, 0.1882) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9373, 0.5412, 0.3843), + rgb(1.0000, 1.0000, 1.0000), + rgb(0.6000, 0.6000, 0.6000) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7922, 0.0000, 0.1255), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.7294, 0.7294, 0.7294), + rgb(0.2510, 0.2510, 0.2510) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7922, 0.0000, 0.1255), + rgb(0.9569, 0.6471, 0.5098), + rgb(1.0000, 1.0000, 1.0000), + rgb(0.7294, 0.7294, 0.7294), + rgb(0.2510, 0.2510, 0.2510) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.9373, 0.5412, 0.3843), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.8784, 0.8784, 0.8784), + rgb(0.6000, 0.6000, 0.6000), + rgb(0.3020, 0.3020, 0.3020) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.9373, 0.5412, 0.3843), + rgb(0.9922, 0.8588, 0.7804), + rgb(1.0000, 1.0000, 1.0000), + rgb(0.8784, 0.8784, 0.8784), + rgb(0.6000, 0.6000, 0.6000), + rgb(0.3020, 0.3020, 0.3020) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.8784, 0.8784, 0.8784), + rgb(0.7294, 0.7294, 0.7294), + rgb(0.5294, 0.5294, 0.5294), + rgb(0.3020, 0.3020, 0.3020) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(1.0000, 1.0000, 1.0000), + rgb(0.8784, 0.8784, 0.8784), + rgb(0.7294, 0.7294, 0.7294), + rgb(0.5294, 0.5294, 0.5294), + rgb(0.3020, 0.3020, 0.3020) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4039, 0.0000, 0.1216), + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(0.8784, 0.8784, 0.8784), + rgb(0.7294, 0.7294, 0.7294), + rgb(0.5294, 0.5294, 0.5294), + rgb(0.3020, 0.3020, 0.3020), + rgb(0.1020, 0.1020, 0.1020) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4039, 0.0000, 0.1216), + rgb(0.6980, 0.0941, 0.1686), + rgb(0.8392, 0.3765, 0.3020), + rgb(0.9569, 0.6471, 0.5098), + rgb(0.9922, 0.8588, 0.7804), + rgb(1.0000, 1.0000, 1.0000), + rgb(0.8784, 0.8784, 0.8784), + rgb(0.7294, 0.7294, 0.7294), + rgb(0.5294, 0.5294, 0.5294), + rgb(0.3020, 0.3020, 0.3020), + rgb(0.1020, 0.1020, 0.1020) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.6392, 0.2510), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.6000, 0.5569, 0.7647) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9020, 0.3804, 0.0039), + rgb(0.9922, 0.7216, 0.3882), + rgb(0.6980, 0.6706, 0.8235), + rgb(0.3686, 0.2353, 0.6000) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.9020, 0.3804, 0.0039), + rgb(0.9922, 0.7216, 0.3882), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.6980, 0.6706, 0.8235), + rgb(0.3686, 0.2353, 0.6000) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.3451, 0.0235), + rgb(0.9451, 0.6392, 0.2510), + rgb(0.9961, 0.8784, 0.7137), + rgb(0.8471, 0.8549, 0.9216), + rgb(0.6000, 0.5569, 0.7647), + rgb(0.3294, 0.1529, 0.5333) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.3451, 0.0235), + rgb(0.9451, 0.6392, 0.2510), + rgb(0.9961, 0.8784, 0.7137), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8471, 0.8549, 0.9216), + rgb(0.6000, 0.5569, 0.7647), + rgb(0.3294, 0.1529, 0.5333) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.3451, 0.0235), + rgb(0.8784, 0.5098, 0.0784), + rgb(0.9922, 0.7216, 0.3882), + rgb(0.9961, 0.8784, 0.7137), + rgb(0.8471, 0.8549, 0.9216), + rgb(0.6980, 0.6706, 0.8235), + rgb(0.5020, 0.4510, 0.6745), + rgb(0.3294, 0.1529, 0.5333) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.3451, 0.0235), + rgb(0.8784, 0.5098, 0.0784), + rgb(0.9922, 0.7216, 0.3882), + rgb(0.9961, 0.8784, 0.7137), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8471, 0.8549, 0.9216), + rgb(0.6980, 0.6706, 0.8235), + rgb(0.5020, 0.4510, 0.6745), + rgb(0.3294, 0.1529, 0.5333) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.2314, 0.0314), + rgb(0.7020, 0.3451, 0.0235), + rgb(0.8784, 0.5098, 0.0784), + rgb(0.9922, 0.7216, 0.3882), + rgb(0.9961, 0.8784, 0.7137), + rgb(0.8471, 0.8549, 0.9216), + rgb(0.6980, 0.6706, 0.8235), + rgb(0.5020, 0.4510, 0.6745), + rgb(0.3294, 0.1529, 0.5333), + rgb(0.1765, 0.0000, 0.2941) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.2314, 0.0314), + rgb(0.7020, 0.3451, 0.0235), + rgb(0.8784, 0.5098, 0.0784), + rgb(0.9922, 0.7216, 0.3882), + rgb(0.9961, 0.8784, 0.7137), + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8471, 0.8549, 0.9216), + rgb(0.6980, 0.6706, 0.8235), + rgb(0.5020, 0.4510, 0.6745), + rgb(0.3294, 0.1529, 0.5333), + rgb(0.1765, 0.0000, 0.2941) + ), ColorBrewer2Type.Diverging + ), + ColorBrewer2Palette( + listOf( + rgb(0.4000, 0.7608, 0.6471), + rgb(0.9882, 0.5529, 0.3843), + rgb(0.5529, 0.6275, 0.7961) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4000, 0.7608, 0.6471), + rgb(0.9882, 0.5529, 0.3843), + rgb(0.5529, 0.6275, 0.7961), + rgb(0.9059, 0.5412, 0.7647) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4000, 0.7608, 0.6471), + rgb(0.9882, 0.5529, 0.3843), + rgb(0.5529, 0.6275, 0.7961), + rgb(0.9059, 0.5412, 0.7647), + rgb(0.6510, 0.8471, 0.3294) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4000, 0.7608, 0.6471), + rgb(0.9882, 0.5529, 0.3843), + rgb(0.5529, 0.6275, 0.7961), + rgb(0.9059, 0.5412, 0.7647), + rgb(0.6510, 0.8471, 0.3294), + rgb(1.0000, 0.8510, 0.1843) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4000, 0.7608, 0.6471), + rgb(0.9882, 0.5529, 0.3843), + rgb(0.5529, 0.6275, 0.7961), + rgb(0.9059, 0.5412, 0.7647), + rgb(0.6510, 0.8471, 0.3294), + rgb(1.0000, 0.8510, 0.1843), + rgb(0.8980, 0.7686, 0.5804) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4000, 0.7608, 0.6471), + rgb(0.9882, 0.5529, 0.3843), + rgb(0.5529, 0.6275, 0.7961), + rgb(0.9059, 0.5412, 0.7647), + rgb(0.6510, 0.8471, 0.3294), + rgb(1.0000, 0.8510, 0.1843), + rgb(0.8980, 0.7686, 0.5804), + rgb(0.7020, 0.7020, 0.7020) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.7882, 0.4980), + rgb(0.7451, 0.6824, 0.8314), + rgb(0.9922, 0.7529, 0.5255) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.7882, 0.4980), + rgb(0.7451, 0.6824, 0.8314), + rgb(0.9922, 0.7529, 0.5255), + rgb(1.0000, 1.0000, 0.6000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.7882, 0.4980), + rgb(0.7451, 0.6824, 0.8314), + rgb(0.9922, 0.7529, 0.5255), + rgb(1.0000, 1.0000, 0.6000), + rgb(0.2196, 0.4235, 0.6902) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.7882, 0.4980), + rgb(0.7451, 0.6824, 0.8314), + rgb(0.9922, 0.7529, 0.5255), + rgb(1.0000, 1.0000, 0.6000), + rgb(0.2196, 0.4235, 0.6902), + rgb(0.9412, 0.0078, 0.4980) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.7882, 0.4980), + rgb(0.7451, 0.6824, 0.8314), + rgb(0.9922, 0.7529, 0.5255), + rgb(1.0000, 1.0000, 0.6000), + rgb(0.2196, 0.4235, 0.6902), + rgb(0.9412, 0.0078, 0.4980), + rgb(0.7490, 0.3569, 0.0902) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.4980, 0.7882, 0.4980), + rgb(0.7451, 0.6824, 0.8314), + rgb(0.9922, 0.7529, 0.5255), + rgb(1.0000, 1.0000, 0.6000), + rgb(0.2196, 0.4235, 0.6902), + rgb(0.9412, 0.0078, 0.4980), + rgb(0.7490, 0.3569, 0.0902), + rgb(0.4000, 0.4000, 0.4000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.8941, 0.1020, 0.1098), + rgb(0.2157, 0.4941, 0.7216), + rgb(0.3020, 0.6863, 0.2902) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.8941, 0.1020, 0.1098), + rgb(0.2157, 0.4941, 0.7216), + rgb(0.3020, 0.6863, 0.2902), + rgb(0.5961, 0.3059, 0.6392) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.8941, 0.1020, 0.1098), + rgb(0.2157, 0.4941, 0.7216), + rgb(0.3020, 0.6863, 0.2902), + rgb(0.5961, 0.3059, 0.6392), + rgb(1.0000, 0.4980, 0.0000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.8941, 0.1020, 0.1098), + rgb(0.2157, 0.4941, 0.7216), + rgb(0.3020, 0.6863, 0.2902), + rgb(0.5961, 0.3059, 0.6392), + rgb(1.0000, 0.4980, 0.0000), + rgb(1.0000, 1.0000, 0.2000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.8941, 0.1020, 0.1098), + rgb(0.2157, 0.4941, 0.7216), + rgb(0.3020, 0.6863, 0.2902), + rgb(0.5961, 0.3059, 0.6392), + rgb(1.0000, 0.4980, 0.0000), + rgb(1.0000, 1.0000, 0.2000), + rgb(0.6510, 0.3373, 0.1569) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.8941, 0.1020, 0.1098), + rgb(0.2157, 0.4941, 0.7216), + rgb(0.3020, 0.6863, 0.2902), + rgb(0.5961, 0.3059, 0.6392), + rgb(1.0000, 0.4980, 0.0000), + rgb(1.0000, 1.0000, 0.2000), + rgb(0.6510, 0.3373, 0.1569), + rgb(0.9686, 0.5059, 0.7490) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.8941, 0.1020, 0.1098), + rgb(0.2157, 0.4941, 0.7216), + rgb(0.3020, 0.6863, 0.2902), + rgb(0.5961, 0.3059, 0.6392), + rgb(1.0000, 0.4980, 0.0000), + rgb(1.0000, 1.0000, 0.2000), + rgb(0.6510, 0.3373, 0.1569), + rgb(0.9686, 0.5059, 0.7490), + rgb(0.6000, 0.6000, 0.6000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275), + rgb(0.9922, 0.7059, 0.3843) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275), + rgb(0.9922, 0.7059, 0.3843), + rgb(0.7020, 0.8706, 0.4118) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275), + rgb(0.9922, 0.7059, 0.3843), + rgb(0.7020, 0.8706, 0.4118), + rgb(0.9882, 0.8039, 0.8980) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275), + rgb(0.9922, 0.7059, 0.3843), + rgb(0.7020, 0.8706, 0.4118), + rgb(0.9882, 0.8039, 0.8980), + rgb(0.8510, 0.8510, 0.8510) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275), + rgb(0.9922, 0.7059, 0.3843), + rgb(0.7020, 0.8706, 0.4118), + rgb(0.9882, 0.8039, 0.8980), + rgb(0.8510, 0.8510, 0.8510), + rgb(0.7373, 0.5020, 0.7412) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275), + rgb(0.9922, 0.7059, 0.3843), + rgb(0.7020, 0.8706, 0.4118), + rgb(0.9882, 0.8039, 0.8980), + rgb(0.8510, 0.8510, 0.8510), + rgb(0.7373, 0.5020, 0.7412), + rgb(0.8000, 0.9216, 0.7725) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.5529, 0.8275, 0.7804), + rgb(1.0000, 1.0000, 0.7020), + rgb(0.7451, 0.7294, 0.8549), + rgb(0.9843, 0.5020, 0.4471), + rgb(0.5020, 0.6941, 0.8275), + rgb(0.9922, 0.7059, 0.3843), + rgb(0.7020, 0.8706, 0.4118), + rgb(0.9882, 0.8039, 0.8980), + rgb(0.8510, 0.8510, 0.8510), + rgb(0.7373, 0.5020, 0.7412), + rgb(0.8000, 0.9216, 0.7725), + rgb(1.0000, 0.9294, 0.4353) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.1059, 0.6196, 0.4667), + rgb(0.8510, 0.3725, 0.0078), + rgb(0.4588, 0.4392, 0.7020) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.1059, 0.6196, 0.4667), + rgb(0.8510, 0.3725, 0.0078), + rgb(0.4588, 0.4392, 0.7020), + rgb(0.9059, 0.1608, 0.5412) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.1059, 0.6196, 0.4667), + rgb(0.8510, 0.3725, 0.0078), + rgb(0.4588, 0.4392, 0.7020), + rgb(0.9059, 0.1608, 0.5412), + rgb(0.4000, 0.6510, 0.1176) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.1059, 0.6196, 0.4667), + rgb(0.8510, 0.3725, 0.0078), + rgb(0.4588, 0.4392, 0.7020), + rgb(0.9059, 0.1608, 0.5412), + rgb(0.4000, 0.6510, 0.1176), + rgb(0.9020, 0.6706, 0.0078) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.1059, 0.6196, 0.4667), + rgb(0.8510, 0.3725, 0.0078), + rgb(0.4588, 0.4392, 0.7020), + rgb(0.9059, 0.1608, 0.5412), + rgb(0.4000, 0.6510, 0.1176), + rgb(0.9020, 0.6706, 0.0078), + rgb(0.6510, 0.4627, 0.1137) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.1059, 0.6196, 0.4667), + rgb(0.8510, 0.3725, 0.0078), + rgb(0.4588, 0.4392, 0.7020), + rgb(0.9059, 0.1608, 0.5412), + rgb(0.4000, 0.6510, 0.1176), + rgb(0.9020, 0.6706, 0.0078), + rgb(0.6510, 0.4627, 0.1137), + rgb(0.4000, 0.4000, 0.4000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000), + rgb(0.8902, 0.1020, 0.1098) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.9922, 0.7490, 0.4353) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.9922, 0.7490, 0.4353), + rgb(1.0000, 0.4980, 0.0000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.9922, 0.7490, 0.4353), + rgb(1.0000, 0.4980, 0.0000), + rgb(0.7922, 0.6980, 0.8392) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.9922, 0.7490, 0.4353), + rgb(1.0000, 0.4980, 0.0000), + rgb(0.7922, 0.6980, 0.8392), + rgb(0.4157, 0.2392, 0.6039) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.9922, 0.7490, 0.4353), + rgb(1.0000, 0.4980, 0.0000), + rgb(0.7922, 0.6980, 0.8392), + rgb(0.4157, 0.2392, 0.6039), + rgb(1.0000, 1.0000, 0.6000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.6510, 0.8078, 0.8902), + rgb(0.1216, 0.4706, 0.7059), + rgb(0.6980, 0.8745, 0.5412), + rgb(0.2000, 0.6275, 0.1725), + rgb(0.9843, 0.6039, 0.6000), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.9922, 0.7490, 0.4353), + rgb(1.0000, 0.4980, 0.0000), + rgb(0.7922, 0.6980, 0.8392), + rgb(0.4157, 0.2392, 0.6039), + rgb(1.0000, 1.0000, 0.6000), + rgb(0.6941, 0.3490, 0.1569) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.8863, 0.8039), + rgb(0.9922, 0.8039, 0.6745), + rgb(0.7961, 0.8353, 0.9098) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.8863, 0.8039), + rgb(0.9922, 0.8039, 0.6745), + rgb(0.7961, 0.8353, 0.9098), + rgb(0.9569, 0.7922, 0.8941) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.8863, 0.8039), + rgb(0.9922, 0.8039, 0.6745), + rgb(0.7961, 0.8353, 0.9098), + rgb(0.9569, 0.7922, 0.8941), + rgb(0.9020, 0.9608, 0.7882) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.8863, 0.8039), + rgb(0.9922, 0.8039, 0.6745), + rgb(0.7961, 0.8353, 0.9098), + rgb(0.9569, 0.7922, 0.8941), + rgb(0.9020, 0.9608, 0.7882), + rgb(1.0000, 0.9490, 0.6824) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.8863, 0.8039), + rgb(0.9922, 0.8039, 0.6745), + rgb(0.7961, 0.8353, 0.9098), + rgb(0.9569, 0.7922, 0.8941), + rgb(0.9020, 0.9608, 0.7882), + rgb(1.0000, 0.9490, 0.6824), + rgb(0.9451, 0.8863, 0.8000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.7020, 0.8863, 0.8039), + rgb(0.9922, 0.8039, 0.6745), + rgb(0.7961, 0.8353, 0.9098), + rgb(0.9569, 0.7922, 0.8941), + rgb(0.9020, 0.9608, 0.7882), + rgb(1.0000, 0.9490, 0.6824), + rgb(0.9451, 0.8863, 0.8000), + rgb(0.8000, 0.8000, 0.8000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9843, 0.7059, 0.6824), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.8000, 0.9216, 0.7725) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9843, 0.7059, 0.6824), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.8706, 0.7961, 0.8941) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9843, 0.7059, 0.6824), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.8706, 0.7961, 0.8941), + rgb(0.9961, 0.8510, 0.6510) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9843, 0.7059, 0.6824), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.8706, 0.7961, 0.8941), + rgb(0.9961, 0.8510, 0.6510), + rgb(1.0000, 1.0000, 0.8000) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9843, 0.7059, 0.6824), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.8706, 0.7961, 0.8941), + rgb(0.9961, 0.8510, 0.6510), + rgb(1.0000, 1.0000, 0.8000), + rgb(0.8980, 0.8471, 0.7412) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9843, 0.7059, 0.6824), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.8706, 0.7961, 0.8941), + rgb(0.9961, 0.8510, 0.6510), + rgb(1.0000, 1.0000, 0.8000), + rgb(0.8980, 0.8471, 0.7412), + rgb(0.9922, 0.8549, 0.9255) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9843, 0.7059, 0.6824), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.8706, 0.7961, 0.8941), + rgb(0.9961, 0.8510, 0.6510), + rgb(1.0000, 1.0000, 0.8000), + rgb(0.8980, 0.8471, 0.7412), + rgb(0.9922, 0.8549, 0.9255), + rgb(0.9490, 0.9490, 0.9490) + ), ColorBrewer2Type.Qualitative + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9098, 0.7843), + rgb(0.9922, 0.7333, 0.5176), + rgb(0.8902, 0.2902, 0.2000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9412, 0.8510), + rgb(0.9922, 0.8000, 0.5412), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.8431, 0.1882, 0.1216) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9412, 0.8510), + rgb(0.9922, 0.8000, 0.5412), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.8902, 0.2902, 0.2000), + rgb(0.7020, 0.0000, 0.0000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9412, 0.8510), + rgb(0.9922, 0.8314, 0.6196), + rgb(0.9922, 0.7333, 0.5176), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.8902, 0.2902, 0.2000), + rgb(0.7020, 0.0000, 0.0000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9412, 0.8510), + rgb(0.9922, 0.8314, 0.6196), + rgb(0.9922, 0.7333, 0.5176), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9373, 0.3961, 0.2824), + rgb(0.8431, 0.1882, 0.1216), + rgb(0.6000, 0.0000, 0.0000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9255), + rgb(0.9961, 0.9098, 0.7843), + rgb(0.9922, 0.8314, 0.6196), + rgb(0.9922, 0.7333, 0.5176), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9373, 0.3961, 0.2824), + rgb(0.8431, 0.1882, 0.1216), + rgb(0.6000, 0.0000, 0.0000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9255), + rgb(0.9961, 0.9098, 0.7843), + rgb(0.9922, 0.8314, 0.6196), + rgb(0.9922, 0.7333, 0.5176), + rgb(0.9882, 0.5529, 0.3490), + rgb(0.9373, 0.3961, 0.2824), + rgb(0.8431, 0.1882, 0.1216), + rgb(0.7020, 0.0000, 0.0000), + rgb(0.4980, 0.0000, 0.0000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9255, 0.9059, 0.9490), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.1686, 0.5490, 0.7451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.7412, 0.7882, 0.8824), + rgb(0.4549, 0.6627, 0.8118), + rgb(0.0196, 0.4392, 0.6902) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.7412, 0.7882, 0.8824), + rgb(0.4549, 0.6627, 0.8118), + rgb(0.1686, 0.5490, 0.7451), + rgb(0.0157, 0.3529, 0.5529) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4549, 0.6627, 0.8118), + rgb(0.1686, 0.5490, 0.7451), + rgb(0.0157, 0.3529, 0.5529) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4549, 0.6627, 0.8118), + rgb(0.2118, 0.5647, 0.7529), + rgb(0.0196, 0.4392, 0.6902), + rgb(0.0118, 0.3059, 0.4824) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9843), + rgb(0.9255, 0.9059, 0.9490), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4549, 0.6627, 0.8118), + rgb(0.2118, 0.5647, 0.7529), + rgb(0.0196, 0.4392, 0.6902), + rgb(0.0118, 0.3059, 0.4824) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9843), + rgb(0.9255, 0.9059, 0.9490), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4549, 0.6627, 0.8118), + rgb(0.2118, 0.5647, 0.7529), + rgb(0.0196, 0.4392, 0.6902), + rgb(0.0157, 0.3529, 0.5529), + rgb(0.0078, 0.2196, 0.3451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.8784, 0.9255, 0.9569), + rgb(0.6196, 0.7373, 0.8549), + rgb(0.5333, 0.3373, 0.6549) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.5490, 0.5882, 0.7765), + rgb(0.5333, 0.2549, 0.6157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.7020, 0.8039, 0.8902), + rgb(0.5490, 0.5882, 0.7765), + rgb(0.5333, 0.3373, 0.6549), + rgb(0.5059, 0.0588, 0.4863) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.7490, 0.8275, 0.9020), + rgb(0.6196, 0.7373, 0.8549), + rgb(0.5490, 0.5882, 0.7765), + rgb(0.5333, 0.3373, 0.6549), + rgb(0.5059, 0.0588, 0.4863) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.7490, 0.8275, 0.9020), + rgb(0.6196, 0.7373, 0.8549), + rgb(0.5490, 0.5882, 0.7765), + rgb(0.5490, 0.4196, 0.6941), + rgb(0.5333, 0.2549, 0.6157), + rgb(0.4314, 0.0039, 0.4196) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9922), + rgb(0.8784, 0.9255, 0.9569), + rgb(0.7490, 0.8275, 0.9020), + rgb(0.6196, 0.7373, 0.8549), + rgb(0.5490, 0.5882, 0.7765), + rgb(0.5490, 0.4196, 0.6941), + rgb(0.5333, 0.2549, 0.6157), + rgb(0.4314, 0.0039, 0.4196) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9922), + rgb(0.8784, 0.9255, 0.9569), + rgb(0.7490, 0.8275, 0.9020), + rgb(0.6196, 0.7373, 0.8549), + rgb(0.5490, 0.5882, 0.7765), + rgb(0.5490, 0.4196, 0.6941), + rgb(0.5333, 0.2549, 0.6157), + rgb(0.5059, 0.0588, 0.4863), + rgb(0.3020, 0.0000, 0.2941) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9020, 0.8078), + rgb(0.9922, 0.6824, 0.4196), + rgb(0.9020, 0.3333, 0.0510) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9294, 0.8706), + rgb(0.9922, 0.7451, 0.5216), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.8510, 0.2784, 0.0039) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9294, 0.8706), + rgb(0.9922, 0.7451, 0.5216), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9020, 0.3333, 0.0510), + rgb(0.6510, 0.2118, 0.0118) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9294, 0.8706), + rgb(0.9922, 0.8157, 0.6353), + rgb(0.9922, 0.6824, 0.4196), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9020, 0.3333, 0.0510), + rgb(0.6510, 0.2118, 0.0118) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9294, 0.8706), + rgb(0.9922, 0.8157, 0.6353), + rgb(0.9922, 0.6824, 0.4196), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9451, 0.4118, 0.0745), + rgb(0.8510, 0.2824, 0.0039), + rgb(0.5490, 0.1765, 0.0157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9608, 0.9216), + rgb(0.9961, 0.9020, 0.8078), + rgb(0.9922, 0.8157, 0.6353), + rgb(0.9922, 0.6824, 0.4196), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9451, 0.4118, 0.0745), + rgb(0.8510, 0.2824, 0.0039), + rgb(0.5490, 0.1765, 0.0157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9608, 0.9216), + rgb(0.9961, 0.9020, 0.8078), + rgb(0.9922, 0.8157, 0.6353), + rgb(0.9922, 0.6824, 0.4196), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9451, 0.4118, 0.0745), + rgb(0.8510, 0.2824, 0.0039), + rgb(0.6510, 0.2118, 0.0118), + rgb(0.4980, 0.1529, 0.0157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.8980, 0.9608, 0.9765), + rgb(0.6000, 0.8471, 0.7882), + rgb(0.1725, 0.6353, 0.3725) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.6980, 0.8863, 0.8863), + rgb(0.4000, 0.7608, 0.6431), + rgb(0.1373, 0.5451, 0.2706) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.6980, 0.8863, 0.8863), + rgb(0.4000, 0.7608, 0.6431), + rgb(0.1725, 0.6353, 0.3725), + rgb(0.0000, 0.4275, 0.1725) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.8000, 0.9255, 0.9020), + rgb(0.6000, 0.8471, 0.7882), + rgb(0.4000, 0.7608, 0.6431), + rgb(0.1725, 0.6353, 0.3725), + rgb(0.0000, 0.4275, 0.1725) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9843), + rgb(0.8000, 0.9255, 0.9020), + rgb(0.6000, 0.8471, 0.7882), + rgb(0.4000, 0.7608, 0.6431), + rgb(0.2549, 0.6824, 0.4627), + rgb(0.1373, 0.5451, 0.2706), + rgb(0.0000, 0.3451, 0.1412) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9922), + rgb(0.8980, 0.9608, 0.9765), + rgb(0.8000, 0.9255, 0.9020), + rgb(0.6000, 0.8471, 0.7882), + rgb(0.4000, 0.7608, 0.6431), + rgb(0.2549, 0.6824, 0.4627), + rgb(0.1373, 0.5451, 0.2706), + rgb(0.0000, 0.3451, 0.1412) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9922), + rgb(0.8980, 0.9608, 0.9765), + rgb(0.8000, 0.9255, 0.9020), + rgb(0.6000, 0.8471, 0.7882), + rgb(0.4000, 0.7608, 0.6431), + rgb(0.2549, 0.6824, 0.4627), + rgb(0.1373, 0.5451, 0.2706), + rgb(0.0000, 0.4275, 0.1725), + rgb(0.0000, 0.2667, 0.1059) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.7373), + rgb(0.9961, 0.7686, 0.3098), + rgb(0.8510, 0.3725, 0.0549) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8314), + rgb(0.9961, 0.8510, 0.5569), + rgb(0.9961, 0.6000, 0.1608), + rgb(0.8000, 0.2980, 0.0078) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8314), + rgb(0.9961, 0.8510, 0.5569), + rgb(0.9961, 0.6000, 0.1608), + rgb(0.8510, 0.3725, 0.0549), + rgb(0.6000, 0.2039, 0.0157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8314), + rgb(0.9961, 0.8902, 0.5686), + rgb(0.9961, 0.7686, 0.3098), + rgb(0.9961, 0.6000, 0.1608), + rgb(0.8510, 0.3725, 0.0549), + rgb(0.6000, 0.2039, 0.0157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8314), + rgb(0.9961, 0.8902, 0.5686), + rgb(0.9961, 0.7686, 0.3098), + rgb(0.9961, 0.6000, 0.1608), + rgb(0.9255, 0.4392, 0.0784), + rgb(0.8000, 0.2980, 0.0078), + rgb(0.5490, 0.1765, 0.0157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8980), + rgb(1.0000, 0.9686, 0.7373), + rgb(0.9961, 0.8902, 0.5686), + rgb(0.9961, 0.7686, 0.3098), + rgb(0.9961, 0.6000, 0.1608), + rgb(0.9255, 0.4392, 0.0784), + rgb(0.8000, 0.2980, 0.0078), + rgb(0.5490, 0.1765, 0.0157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8980), + rgb(1.0000, 0.9686, 0.7373), + rgb(0.9961, 0.8902, 0.5686), + rgb(0.9961, 0.7686, 0.3098), + rgb(0.9961, 0.6000, 0.1608), + rgb(0.9255, 0.4392, 0.0784), + rgb(0.8000, 0.2980, 0.0078), + rgb(0.6000, 0.2039, 0.0157), + rgb(0.4000, 0.1451, 0.0235) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.7255), + rgb(0.6784, 0.8667, 0.5569), + rgb(0.1922, 0.6392, 0.3294) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.7608, 0.9020, 0.6000), + rgb(0.4706, 0.7765, 0.4745), + rgb(0.1373, 0.5176, 0.2627) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.7608, 0.9020, 0.6000), + rgb(0.4706, 0.7765, 0.4745), + rgb(0.1922, 0.6392, 0.3294), + rgb(0.0000, 0.4078, 0.2157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.8510, 0.9412, 0.6392), + rgb(0.6784, 0.8667, 0.5569), + rgb(0.4706, 0.7765, 0.4745), + rgb(0.1922, 0.6392, 0.3294), + rgb(0.0000, 0.4078, 0.2157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.8510, 0.9412, 0.6392), + rgb(0.6784, 0.8667, 0.5569), + rgb(0.4706, 0.7765, 0.4745), + rgb(0.2549, 0.6706, 0.3647), + rgb(0.1373, 0.5176, 0.2627), + rgb(0.0000, 0.3529, 0.1961) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8980), + rgb(0.9686, 0.9882, 0.7255), + rgb(0.8510, 0.9412, 0.6392), + rgb(0.6784, 0.8667, 0.5569), + rgb(0.4706, 0.7765, 0.4745), + rgb(0.2549, 0.6706, 0.3647), + rgb(0.1373, 0.5176, 0.2627), + rgb(0.0000, 0.3529, 0.1961) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8980), + rgb(0.9686, 0.9882, 0.7255), + rgb(0.8510, 0.9412, 0.6392), + rgb(0.6784, 0.8667, 0.5569), + rgb(0.4706, 0.7765, 0.4745), + rgb(0.2549, 0.6706, 0.3647), + rgb(0.1373, 0.5176, 0.2627), + rgb(0.0000, 0.4078, 0.2157), + rgb(0.0000, 0.2706, 0.1608) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.8784, 0.8235), + rgb(0.9882, 0.5725, 0.4471), + rgb(0.8706, 0.1765, 0.1490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.8980, 0.8510), + rgb(0.9882, 0.6824, 0.5686), + rgb(0.9843, 0.4157, 0.2902), + rgb(0.7961, 0.0941, 0.1137) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.8980, 0.8510), + rgb(0.9882, 0.6824, 0.5686), + rgb(0.9843, 0.4157, 0.2902), + rgb(0.8706, 0.1765, 0.1490), + rgb(0.6471, 0.0588, 0.0824) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.8980, 0.8510), + rgb(0.9882, 0.7333, 0.6314), + rgb(0.9882, 0.5725, 0.4471), + rgb(0.9843, 0.4157, 0.2902), + rgb(0.8706, 0.1765, 0.1490), + rgb(0.6471, 0.0588, 0.0824) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.8980, 0.8510), + rgb(0.9882, 0.7333, 0.6314), + rgb(0.9882, 0.5725, 0.4471), + rgb(0.9843, 0.4157, 0.2902), + rgb(0.9373, 0.2314, 0.1725), + rgb(0.7961, 0.0941, 0.1137), + rgb(0.6000, 0.0000, 0.0510) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9608, 0.9412), + rgb(0.9961, 0.8784, 0.8235), + rgb(0.9882, 0.7333, 0.6314), + rgb(0.9882, 0.5725, 0.4471), + rgb(0.9843, 0.4157, 0.2902), + rgb(0.9373, 0.2314, 0.1725), + rgb(0.7961, 0.0941, 0.1137), + rgb(0.6000, 0.0000, 0.0510) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9608, 0.9412), + rgb(0.9961, 0.8784, 0.8235), + rgb(0.9882, 0.7333, 0.6314), + rgb(0.9882, 0.5725, 0.4471), + rgb(0.9843, 0.4157, 0.2902), + rgb(0.9373, 0.2314, 0.1725), + rgb(0.7961, 0.0941, 0.1137), + rgb(0.6471, 0.0588, 0.0824), + rgb(0.4039, 0.0000, 0.0510) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9922, 0.8784, 0.8667), + rgb(0.9804, 0.6235, 0.7098), + rgb(0.7725, 0.1059, 0.5412) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9216, 0.8863), + rgb(0.9843, 0.7059, 0.7255), + rgb(0.9686, 0.4078, 0.6314), + rgb(0.6824, 0.0039, 0.4941) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9216, 0.8863), + rgb(0.9843, 0.7059, 0.7255), + rgb(0.9686, 0.4078, 0.6314), + rgb(0.7725, 0.1059, 0.5412), + rgb(0.4784, 0.0039, 0.4667) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9216, 0.8863), + rgb(0.9882, 0.7725, 0.7529), + rgb(0.9804, 0.6235, 0.7098), + rgb(0.9686, 0.4078, 0.6314), + rgb(0.7725, 0.1059, 0.5412), + rgb(0.4784, 0.0039, 0.4667) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9961, 0.9216, 0.8863), + rgb(0.9882, 0.7725, 0.7529), + rgb(0.9804, 0.6235, 0.7098), + rgb(0.9686, 0.4078, 0.6314), + rgb(0.8667, 0.2039, 0.5922), + rgb(0.6824, 0.0039, 0.4941), + rgb(0.4784, 0.0039, 0.4667) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9529), + rgb(0.9922, 0.8784, 0.8667), + rgb(0.9882, 0.7725, 0.7529), + rgb(0.9804, 0.6235, 0.7098), + rgb(0.9686, 0.4078, 0.6314), + rgb(0.8667, 0.2039, 0.5922), + rgb(0.6824, 0.0039, 0.4941), + rgb(0.4784, 0.0039, 0.4667) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9529), + rgb(0.9922, 0.8784, 0.8667), + rgb(0.9882, 0.7725, 0.7529), + rgb(0.9804, 0.6235, 0.7098), + rgb(0.9686, 0.4078, 0.6314), + rgb(0.8667, 0.2039, 0.5922), + rgb(0.6824, 0.0039, 0.4941), + rgb(0.4784, 0.0039, 0.4667), + rgb(0.2863, 0.0000, 0.4157) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.8980, 0.9608, 0.8784), + rgb(0.6314, 0.8510, 0.6078), + rgb(0.1922, 0.6392, 0.3294) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9137), + rgb(0.7294, 0.8941, 0.7020), + rgb(0.4549, 0.7686, 0.4627), + rgb(0.1373, 0.5451, 0.2706) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9137), + rgb(0.7294, 0.8941, 0.7020), + rgb(0.4549, 0.7686, 0.4627), + rgb(0.1922, 0.6392, 0.3294), + rgb(0.0000, 0.4275, 0.1725) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9137), + rgb(0.7804, 0.9137, 0.7529), + rgb(0.6314, 0.8510, 0.6078), + rgb(0.4549, 0.7686, 0.4627), + rgb(0.1922, 0.6392, 0.3294), + rgb(0.0000, 0.4275, 0.1725) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.9137), + rgb(0.7804, 0.9137, 0.7529), + rgb(0.6314, 0.8510, 0.6078), + rgb(0.4549, 0.7686, 0.4627), + rgb(0.2549, 0.6706, 0.3647), + rgb(0.1373, 0.5451, 0.2706), + rgb(0.0000, 0.3529, 0.1961) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9608), + rgb(0.8980, 0.9608, 0.8784), + rgb(0.7804, 0.9137, 0.7529), + rgb(0.6314, 0.8510, 0.6078), + rgb(0.4549, 0.7686, 0.4627), + rgb(0.2549, 0.6706, 0.3647), + rgb(0.1373, 0.5451, 0.2706), + rgb(0.0000, 0.3529, 0.1961) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9608), + rgb(0.8980, 0.9608, 0.8784), + rgb(0.7804, 0.9137, 0.7529), + rgb(0.6314, 0.8510, 0.6078), + rgb(0.4549, 0.7686, 0.4627), + rgb(0.2549, 0.6706, 0.3647), + rgb(0.1373, 0.5451, 0.2706), + rgb(0.0000, 0.4275, 0.1725), + rgb(0.0000, 0.2667, 0.1059) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9294, 0.9725, 0.6941), + rgb(0.4980, 0.8039, 0.7333), + rgb(0.1725, 0.4980, 0.7216) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.6314, 0.8549, 0.7059), + rgb(0.2549, 0.7137, 0.7686), + rgb(0.1333, 0.3686, 0.6588) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.6314, 0.8549, 0.7059), + rgb(0.2549, 0.7137, 0.7686), + rgb(0.1725, 0.4980, 0.7216), + rgb(0.1451, 0.2039, 0.5804) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.7804, 0.9137, 0.7059), + rgb(0.4980, 0.8039, 0.7333), + rgb(0.2549, 0.7137, 0.7686), + rgb(0.1725, 0.4980, 0.7216), + rgb(0.1451, 0.2039, 0.5804) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(0.7804, 0.9137, 0.7059), + rgb(0.4980, 0.8039, 0.7333), + rgb(0.2549, 0.7137, 0.7686), + rgb(0.1137, 0.5686, 0.7529), + rgb(0.1333, 0.3686, 0.6588), + rgb(0.0471, 0.1725, 0.5176) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8510), + rgb(0.9294, 0.9725, 0.6941), + rgb(0.7804, 0.9137, 0.7059), + rgb(0.4980, 0.8039, 0.7333), + rgb(0.2549, 0.7137, 0.7686), + rgb(0.1137, 0.5686, 0.7529), + rgb(0.1333, 0.3686, 0.6588), + rgb(0.0471, 0.1725, 0.5176) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8510), + rgb(0.9294, 0.9725, 0.6941), + rgb(0.7804, 0.9137, 0.7059), + rgb(0.4980, 0.8039, 0.7333), + rgb(0.2549, 0.7137, 0.7686), + rgb(0.1137, 0.5686, 0.7529), + rgb(0.1333, 0.3686, 0.6588), + rgb(0.1451, 0.2039, 0.5804), + rgb(0.0314, 0.1137, 0.3451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9373, 0.9294, 0.9608), + rgb(0.7373, 0.7412, 0.8627), + rgb(0.4588, 0.4196, 0.6941) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9490, 0.9412, 0.9686), + rgb(0.7961, 0.7882, 0.8863), + rgb(0.6196, 0.6039, 0.7843), + rgb(0.4157, 0.3176, 0.6392) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9490, 0.9412, 0.9686), + rgb(0.7961, 0.7882, 0.8863), + rgb(0.6196, 0.6039, 0.7843), + rgb(0.4588, 0.4196, 0.6941), + rgb(0.3294, 0.1529, 0.5608) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9490, 0.9412, 0.9686), + rgb(0.8549, 0.8549, 0.9216), + rgb(0.7373, 0.7412, 0.8627), + rgb(0.6196, 0.6039, 0.7843), + rgb(0.4588, 0.4196, 0.6941), + rgb(0.3294, 0.1529, 0.5608) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9490, 0.9412, 0.9686), + rgb(0.8549, 0.8549, 0.9216), + rgb(0.7373, 0.7412, 0.8627), + rgb(0.6196, 0.6039, 0.7843), + rgb(0.5020, 0.4902, 0.7294), + rgb(0.4157, 0.3176, 0.6392), + rgb(0.2902, 0.0784, 0.5255) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9882, 0.9843, 0.9922), + rgb(0.9373, 0.9294, 0.9608), + rgb(0.8549, 0.8549, 0.9216), + rgb(0.7373, 0.7412, 0.8627), + rgb(0.6196, 0.6039, 0.7843), + rgb(0.5020, 0.4902, 0.7294), + rgb(0.4157, 0.3176, 0.6392), + rgb(0.2902, 0.0784, 0.5255) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9882, 0.9843, 0.9922), + rgb(0.9373, 0.9294, 0.9608), + rgb(0.8549, 0.8549, 0.9216), + rgb(0.7373, 0.7412, 0.8627), + rgb(0.6196, 0.6039, 0.7843), + rgb(0.5020, 0.4902, 0.7294), + rgb(0.4157, 0.3176, 0.6392), + rgb(0.3294, 0.1529, 0.5608), + rgb(0.2471, 0.0000, 0.4902) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.8784, 0.9529, 0.8588), + rgb(0.6588, 0.8667, 0.7098), + rgb(0.2627, 0.6353, 0.7922) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9412, 0.9765, 0.9098), + rgb(0.7294, 0.8941, 0.7373), + rgb(0.4824, 0.8000, 0.7686), + rgb(0.1686, 0.5490, 0.7451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9412, 0.9765, 0.9098), + rgb(0.7294, 0.8941, 0.7373), + rgb(0.4824, 0.8000, 0.7686), + rgb(0.2627, 0.6353, 0.7922), + rgb(0.0314, 0.4078, 0.6745) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9412, 0.9765, 0.9098), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.6588, 0.8667, 0.7098), + rgb(0.4824, 0.8000, 0.7686), + rgb(0.2627, 0.6353, 0.7922), + rgb(0.0314, 0.4078, 0.6745) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9412, 0.9765, 0.9098), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.6588, 0.8667, 0.7098), + rgb(0.4824, 0.8000, 0.7686), + rgb(0.3059, 0.7020, 0.8275), + rgb(0.1686, 0.5490, 0.7451), + rgb(0.0314, 0.3451, 0.6196) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9412), + rgb(0.8784, 0.9529, 0.8588), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.6588, 0.8667, 0.7098), + rgb(0.4824, 0.8000, 0.7686), + rgb(0.3059, 0.7020, 0.8275), + rgb(0.1686, 0.5490, 0.7451), + rgb(0.0314, 0.3451, 0.6196) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9882, 0.9412), + rgb(0.8784, 0.9529, 0.8588), + rgb(0.8000, 0.9216, 0.7725), + rgb(0.6588, 0.8667, 0.7098), + rgb(0.4824, 0.8000, 0.7686), + rgb(0.3059, 0.7020, 0.8275), + rgb(0.1686, 0.5490, 0.7451), + rgb(0.0314, 0.4078, 0.6745), + rgb(0.0314, 0.2510, 0.5059) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9412, 0.9412, 0.9412), + rgb(0.7412, 0.7412, 0.7412), + rgb(0.3882, 0.3882, 0.3882) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8000, 0.8000, 0.8000), + rgb(0.5882, 0.5882, 0.5882), + rgb(0.3216, 0.3216, 0.3216) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8000, 0.8000, 0.8000), + rgb(0.5882, 0.5882, 0.5882), + rgb(0.3882, 0.3882, 0.3882), + rgb(0.1451, 0.1451, 0.1451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8510, 0.8510, 0.8510), + rgb(0.7412, 0.7412, 0.7412), + rgb(0.5882, 0.5882, 0.5882), + rgb(0.3882, 0.3882, 0.3882), + rgb(0.1451, 0.1451, 0.1451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9686, 0.9686), + rgb(0.8510, 0.8510, 0.8510), + rgb(0.7412, 0.7412, 0.7412), + rgb(0.5882, 0.5882, 0.5882), + rgb(0.4510, 0.4510, 0.4510), + rgb(0.3216, 0.3216, 0.3216), + rgb(0.1451, 0.1451, 0.1451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 1.0000), + rgb(0.9412, 0.9412, 0.9412), + rgb(0.8510, 0.8510, 0.8510), + rgb(0.7412, 0.7412, 0.7412), + rgb(0.5882, 0.5882, 0.5882), + rgb(0.4510, 0.4510, 0.4510), + rgb(0.3216, 0.3216, 0.3216), + rgb(0.1451, 0.1451, 0.1451) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 1.0000), + rgb(0.9412, 0.9412, 0.9412), + rgb(0.8510, 0.8510, 0.8510), + rgb(0.7412, 0.7412, 0.7412), + rgb(0.5882, 0.5882, 0.5882), + rgb(0.4510, 0.4510, 0.4510), + rgb(0.3216, 0.3216, 0.3216), + rgb(0.1451, 0.1451, 0.1451), + rgb(0.0000, 0.0000, 0.0000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9294, 0.6275), + rgb(0.9961, 0.6980, 0.2980), + rgb(0.9412, 0.2314, 0.1255) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.6980), + rgb(0.9961, 0.8000, 0.3608), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.8902, 0.1020, 0.1098) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.6980), + rgb(0.9961, 0.8000, 0.3608), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9412, 0.2314, 0.1255), + rgb(0.7412, 0.0000, 0.1490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.6980), + rgb(0.9961, 0.8510, 0.4627), + rgb(0.9961, 0.6980, 0.2980), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9412, 0.2314, 0.1255), + rgb(0.7412, 0.0000, 0.1490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.6980), + rgb(0.9961, 0.8510, 0.4627), + rgb(0.9961, 0.6980, 0.2980), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9882, 0.3059, 0.1647), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.6941, 0.0000, 0.1490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(1.0000, 0.9294, 0.6275), + rgb(0.9961, 0.8510, 0.4627), + rgb(0.9961, 0.6980, 0.2980), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9882, 0.3059, 0.1647), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.6941, 0.0000, 0.1490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 1.0000, 0.8000), + rgb(1.0000, 0.9294, 0.6275), + rgb(0.9961, 0.8510, 0.4627), + rgb(0.9961, 0.6980, 0.2980), + rgb(0.9922, 0.5529, 0.2353), + rgb(0.9882, 0.3059, 0.1647), + rgb(0.8902, 0.1020, 0.1098), + rgb(0.7412, 0.0000, 0.1490), + rgb(0.5020, 0.0000, 0.1490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9059, 0.8824, 0.9373), + rgb(0.7882, 0.5804, 0.7804), + rgb(0.8667, 0.1098, 0.4667) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.8431, 0.7098, 0.8471), + rgb(0.8745, 0.3961, 0.6902), + rgb(0.8078, 0.0706, 0.3373) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.8431, 0.7098, 0.8471), + rgb(0.8745, 0.3961, 0.6902), + rgb(0.8667, 0.1098, 0.4667), + rgb(0.5961, 0.0000, 0.2627) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.8314, 0.7255, 0.8549), + rgb(0.7882, 0.5804, 0.7804), + rgb(0.8745, 0.3961, 0.6902), + rgb(0.8667, 0.1098, 0.4667), + rgb(0.5961, 0.0000, 0.2627) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9451, 0.9333, 0.9647), + rgb(0.8314, 0.7255, 0.8549), + rgb(0.7882, 0.5804, 0.7804), + rgb(0.8745, 0.3961, 0.6902), + rgb(0.9059, 0.1608, 0.5412), + rgb(0.8078, 0.0706, 0.3373), + rgb(0.5686, 0.0000, 0.2471) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9569, 0.9765), + rgb(0.9059, 0.8824, 0.9373), + rgb(0.8314, 0.7255, 0.8549), + rgb(0.7882, 0.5804, 0.7804), + rgb(0.8745, 0.3961, 0.6902), + rgb(0.9059, 0.1608, 0.5412), + rgb(0.8078, 0.0706, 0.3373), + rgb(0.5686, 0.0000, 0.2471) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9569, 0.9765), + rgb(0.9059, 0.8824, 0.9373), + rgb(0.8314, 0.7255, 0.8549), + rgb(0.7882, 0.5804, 0.7804), + rgb(0.8745, 0.3961, 0.6902), + rgb(0.9059, 0.1608, 0.5412), + rgb(0.8078, 0.0706, 0.3373), + rgb(0.5961, 0.0000, 0.2627), + rgb(0.4039, 0.0000, 0.1216) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.8706, 0.9216, 0.9686), + rgb(0.6196, 0.7922, 0.8824), + rgb(0.1922, 0.5098, 0.7412) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9373, 0.9529, 1.0000), + rgb(0.7412, 0.8431, 0.9059), + rgb(0.4196, 0.6824, 0.8392), + rgb(0.1294, 0.4431, 0.7098) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9373, 0.9529, 1.0000), + rgb(0.7412, 0.8431, 0.9059), + rgb(0.4196, 0.6824, 0.8392), + rgb(0.1922, 0.5098, 0.7412), + rgb(0.0314, 0.3176, 0.6118) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9373, 0.9529, 1.0000), + rgb(0.7765, 0.8588, 0.9373), + rgb(0.6196, 0.7922, 0.8824), + rgb(0.4196, 0.6824, 0.8392), + rgb(0.1922, 0.5098, 0.7412), + rgb(0.0314, 0.3176, 0.6118) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9373, 0.9529, 1.0000), + rgb(0.7765, 0.8588, 0.9373), + rgb(0.6196, 0.7922, 0.8824), + rgb(0.4196, 0.6824, 0.8392), + rgb(0.2588, 0.5725, 0.7765), + rgb(0.1294, 0.4431, 0.7098), + rgb(0.0314, 0.2706, 0.5804) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9843, 1.0000), + rgb(0.8706, 0.9216, 0.9686), + rgb(0.7765, 0.8588, 0.9373), + rgb(0.6196, 0.7922, 0.8824), + rgb(0.4196, 0.6824, 0.8392), + rgb(0.2588, 0.5725, 0.7765), + rgb(0.1294, 0.4431, 0.7098), + rgb(0.0314, 0.2706, 0.5804) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9686, 0.9843, 1.0000), + rgb(0.8706, 0.9216, 0.9686), + rgb(0.7765, 0.8588, 0.9373), + rgb(0.6196, 0.7922, 0.8824), + rgb(0.4196, 0.6824, 0.8392), + rgb(0.2588, 0.5725, 0.7765), + rgb(0.1294, 0.4431, 0.7098), + rgb(0.0314, 0.3176, 0.6118), + rgb(0.0314, 0.1882, 0.4196) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9255, 0.8863, 0.9412), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.1098, 0.5647, 0.6000) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9647, 0.9373, 0.9686), + rgb(0.7412, 0.7882, 0.8824), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.0078, 0.5059, 0.5412) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9647, 0.9373, 0.9686), + rgb(0.7412, 0.7882, 0.8824), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.1098, 0.5647, 0.6000), + rgb(0.0039, 0.4235, 0.3490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9647, 0.9373, 0.9686), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.1098, 0.5647, 0.6000), + rgb(0.0039, 0.4235, 0.3490) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(0.9647, 0.9373, 0.9686), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.2118, 0.5647, 0.7529), + rgb(0.0078, 0.5059, 0.5412), + rgb(0.0039, 0.3922, 0.3137) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9843), + rgb(0.9255, 0.8863, 0.9412), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.2118, 0.5647, 0.7529), + rgb(0.0078, 0.5059, 0.5412), + rgb(0.0039, 0.3922, 0.3137) + ), ColorBrewer2Type.Sequential + ), + ColorBrewer2Palette( + listOf( + rgb(1.0000, 0.9686, 0.9843), + rgb(0.9255, 0.8863, 0.9412), + rgb(0.8157, 0.8196, 0.9020), + rgb(0.6510, 0.7412, 0.8588), + rgb(0.4039, 0.6627, 0.8118), + rgb(0.2118, 0.5647, 0.7529), + rgb(0.0078, 0.5059, 0.5412), + rgb(0.0039, 0.4235, 0.3490), + rgb(0.0039, 0.2745, 0.2118) + ), ColorBrewer2Type.Sequential + ) +) + +fun colorBrewer2Palettes( + numberOfColors: Int? = null, + paletteType: ColorBrewer2Type = ColorBrewer2Type.Any +) = when { + numberOfColors == null && paletteType == ColorBrewer2Type.Any -> colorBrewer2 + paletteType == ColorBrewer2Type.Any -> colorBrewer2.filter { it.colors.size == numberOfColors } + else -> colorBrewer2.filter { it.type == paletteType } +} diff --git a/android/src/main/java/com/icegps/orx/ktx/ColorRGBa.kt b/android/src/main/java/com/icegps/orx/ktx/ColorRGBa.kt index 098e04a3..05f8c638 100644 --- a/android/src/main/java/com/icegps/orx/ktx/ColorRGBa.kt +++ b/android/src/main/java/com/icegps/orx/ktx/ColorRGBa.kt @@ -1,6 +1,6 @@ package com.icegps.orx.ktx -import org.openrndr.color.ColorRGBa +import com.icegps.orx.color.ColorRGBa /** * @author tabidachinokaze diff --git a/android/src/main/java/com/icegps/orx/ktx/Vector2.kt b/android/src/main/java/com/icegps/orx/ktx/Vector2.kt deleted file mode 100644 index bc87dc4b..00000000 --- a/android/src/main/java/com/icegps/orx/ktx/Vector2.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.icegps.orx.ktx - -import com.icegps.common.helper.GeoHelper -import com.mapbox.geojson.Point -import org.openrndr.math.Vector2 - -fun Vector2.niceStr(): String { - return "[$x, $y, 0.0]".format(this) -} - -fun List.niceStr(): String { - return joinToString(", ", "[", "]") { - it.niceStr() - } -} - -fun Vector2.toMapboxPoint(): Point { - val geoHelper = GeoHelper.getSharedInstance() - return geoHelper.enuToWGS84Object(GeoHelper.ENU(x, y)).run { - Point.fromLngLat(lon, lat, hgt) - } -} \ No newline at end of file diff --git a/android/src/main/java/com/icegps/orx/ktx/Vector2D.kt b/android/src/main/java/com/icegps/orx/ktx/Vector2D.kt index 7761afe7..327f98e4 100644 --- a/android/src/main/java/com/icegps/orx/ktx/Vector2D.kt +++ b/android/src/main/java/com/icegps/orx/ktx/Vector2D.kt @@ -12,4 +12,13 @@ fun Vector2D.toMapboxPoint(): Point { val geoHelper = GeoHelper.getSharedInstance() val wgs84 = geoHelper.enuToWGS84Object(GeoHelper.ENU(x = x, y = y)) return Point.fromLngLat(wgs84.lon, wgs84.lat) -} \ No newline at end of file +} + +/** + * Interpolates between the current vector and the given vector `o` by the specified mixing factor. + * + * @param o The target vector to interpolate towards. + * @param mix A mixing factor between 0 and 1 where `0` results in the current vector and `1` results in the vector `o`. + * @return A new vector that is the result of the interpolation. + */ +fun Vector2D.mix(o: Vector2D, mix: Double): Vector2D = this * (1 - mix) + o * mix diff --git a/android/src/main/java/com/icegps/orx/ktx/Vector3.kt b/android/src/main/java/com/icegps/orx/ktx/Vector3.kt deleted file mode 100644 index 79263ffd..00000000 --- a/android/src/main/java/com/icegps/orx/ktx/Vector3.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.icegps.orx.ktx - -import org.openrndr.math.Vector3 - -fun Vector3.niceStr(): String { - return "[$x, $y, $z]".format(this) -} - -fun List.niceStr(): String { - return joinToString(", ", "[", "]") { - it.niceStr() - } -} - -val List.area: org.openrndr.shape.Rectangle - get() { - val minX = minOf { it.x } - val maxX = maxOf { it.x } - val minY = minOf { it.y } - val maxY = maxOf { it.y } - return org.openrndr.shape.Rectangle(x = minX, y = minY, width = maxX - minX, height = maxY - minY) - } diff --git a/android/src/main/java/com/icegps/orx/marchingsquares/MarchingSquares.kt b/android/src/main/java/com/icegps/orx/marchingsquares/MarchingSquares.kt new file mode 100644 index 00000000..ea1e79e3 --- /dev/null +++ b/android/src/main/java/com/icegps/orx/marchingsquares/MarchingSquares.kt @@ -0,0 +1,219 @@ +package com.icegps.orx.marchingsquares + +import com.icegps.math.geometry.Rectangle +import com.icegps.math.geometry.Vector2D +import com.icegps.math.geometry.Vector2I +import com.icegps.orx.ktx.mix +import kotlin.math.max +import kotlin.math.min + +private const val closeEpsilon = 1E-6 + +data class Segment2D( + val start: Vector2D, + val control: List, + val end: Vector2D, + val corner: Boolean = false +) + +fun Segment2D(start: Vector2D, end: Vector2D, corner: Boolean = true) = + Segment2D(start, emptyList(), end, corner) + +fun Segment2D(start: Vector2D, c0: Vector2D, c1: Vector2D, end: Vector2D, corner: Boolean = true) = + Segment2D(start, listOf(c0, c1), end, corner) + +data class ShapeContour( + val segments: List, + val closed: Boolean, +) { + companion object { + val EMPTY = ShapeContour( + segments = emptyList(), + closed = false, + ) + + /** + * Creates a ShapeContour from a list of points, specifying whether the contour is closed and its y-axis polarity. + * + * @param points A list of points (Vector2) defining the vertices of the contour. + * @param closed Boolean indicating whether the contour should be closed (forms a loop). + * @return A ShapeContour object representing the resulting contour. + */ + fun fromPoints( + points: List, + closed: Boolean, + ): ShapeContour = if (points.isEmpty()) { + EMPTY + } else { + if (!closed) { + ShapeContour((0 until points.size - 1).map { + Segment2D( + points[it], + points[it + 1] + ) + }, false) + } else { + val d = (points.last() - points.first()).lengthSquared + val usePoints = if (d > closeEpsilon) points else points.dropLast(1) + ShapeContour((usePoints.indices).map { + Segment2D( + usePoints[it], + usePoints[(it + 1) % usePoints.size] + ) + }, true) + } + } + } +} + +data class LineSegment(val start: Vector2D, val end: Vector2D) + +/** + * Find contours for a function [f] using the marching squares algorithm. A contour is found when f(x) crosses zero. + * @param f the function + * @param area a rectangular area in which the function should be evaluated + * @param cellSize the size of the cells, smaller size gives higher resolution + * @param useInterpolation intersection points will be interpolated if true, default true + * @return a list of [ShapeContour] instances + */ +fun findContours( + f: (Vector2D) -> Double, + area: Rectangle, + cellSize: Double, + useInterpolation: Boolean = true +): List { + val segments = mutableListOf() + val values = mutableMapOf() + val segmentsMap = mutableMapOf>() + + for (y in 0 until (area.height / cellSize).toInt()) { + for (x in 0 until (area.width / cellSize).toInt()) { + values[Vector2I(x, y)] = f(Vector2D(x * cellSize + area.x, y * cellSize + area.y)) + } + } + + val zero = 0.0 + for (y in 0 until (area.height / cellSize).toInt()) { + for (x in 0 until (area.width / cellSize).toInt()) { + + // Here we check if we are at a right or top border. This is to ensure we create closed contours + // later on in the process. + val v00 = if (x == 0 || y == 0) zero else (values[Vector2I(x, y)] ?: zero) + val v10 = if (y == 0) zero else (values[Vector2I(x + 1, y)] ?: zero) + val v01 = if (x == 0) zero else (values[Vector2I(x, y + 1)] ?: zero) + val v11 = (values[Vector2I(x + 1, y + 1)] ?: zero) + + val p00 = Vector2D(x.toDouble(), y.toDouble()) * cellSize + area.topLeft + val p10 = Vector2D((x + 1).toDouble(), y.toDouble()) * cellSize + area.topLeft + val p01 = Vector2D(x.toDouble(), (y + 1).toDouble()) * cellSize + area.topLeft + val p11 = Vector2D((x + 1).toDouble(), (y + 1).toDouble()) * cellSize + area.topLeft + + val index = (if (v00 >= 0.0) 1 else 0) + + (if (v10 >= 0.0) 2 else 0) + + (if (v01 >= 0.0) 4 else 0) + + (if (v11 >= 0.0) 8 else 0) + + fun blend(v1: Double, v2: Double): Double { + if (useInterpolation) { + require(!v1.isNaN() && !v2.isNaN()) { + "Input values v1=$v1 or v2=$v2 are NaN, which is not allowed." + } + val f1 = min(v1, v2) + val f2 = max(v1, v2) + val v = (-f1) / (f2 - f1) + + require(v == v && v in 0.0..1.0) { + "Invalid value calculated during interpolation: v=$v" + } + + return if (f1 == v1) { + v + } else { + 1.0 - v + } + } else { + return 0.5 + } + } + + fun emitLine( + p00: Vector2D, p01: Vector2D, v00: Double, v01: Double, + p10: Vector2D, p11: Vector2D, v10: Double, v11: Double + ) { + val r0 = blend(v00, v01) + val r1 = blend(v10, v11) + + val v0 = p00.mix(p01, r0) + val v1 = p10.mix(p11, r1) + val l0 = LineSegment(v0, v1) + segmentsMap.getOrPut(v1) { mutableListOf() }.add(l0) + segmentsMap.getOrPut(v0) { mutableListOf() }.add(l0) + segments.add(l0) + } + + when (index) { + 0, 15 -> {} + 1, 15 xor 1 -> { + emitLine(p00, p01, v00, v01, p00, p10, v00, v10) + } + + 2, 15 xor 2 -> { + emitLine(p00, p10, v00, v10, p10, p11, v10, v11) + } + + 3, 15 xor 3 -> { + emitLine(p00, p01, v00, v01, p10, p11, v10, v11) + } + + 4, 15 xor 4 -> { + emitLine(p00, p01, v00, v01, p01, p11, v01, v11) + } + + 5, 15 xor 5 -> { + emitLine(p00, p10, v00, v10, p01, p11, v01, v11) + } + + 6, 15 xor 6 -> { + emitLine(p00, p01, v00, v01, p00, p10, v00, v10) + emitLine(p01, p11, v01, v11, p10, p11, v10, v11) + } + + 7, 15 xor 7 -> { + emitLine(p01, p11, v01, v11, p10, p11, v10, v11) + } + } + } + } + + val processedSegments = mutableSetOf() + val contours = mutableListOf() + for (segment in segments) { + if (segment in processedSegments) { + continue + } else { + val collected = mutableListOf() + var current: LineSegment? = segment + var closed = true + var lastVertex = Vector2D.INFINITY + do { + current!! + if (lastVertex.squaredDistanceTo(current.start) > 1E-5) { + collected.add(current.start) + } + lastVertex = current.start + processedSegments.add(current) + if (segmentsMap[current.start]!!.size < 2) { + closed = false + } + val hold = current + current = segmentsMap[current.start]?.firstOrNull { it !in processedSegments } + if (current == null) { + current = segmentsMap[hold.end]?.firstOrNull { it !in processedSegments } + } + } while (current != segment && current != null) + + contours.add(ShapeContour.fromPoints(collected, closed = closed)) + } + } + return contours +} \ No newline at end of file diff --git a/android/src/main/java/com/icegps/orx/triangulation/DelaunayTriangulation3D.kt b/android/src/main/java/com/icegps/orx/triangulation/DelaunayTriangulation3D.kt deleted file mode 100644 index 02cd6b68..00000000 --- a/android/src/main/java/com/icegps/orx/triangulation/DelaunayTriangulation3D.kt +++ /dev/null @@ -1,91 +0,0 @@ -package com.icegps.orx.triangulation - -import org.openrndr.extra.triangulation.Delaunay -import org.openrndr.math.Vector3 -import org.openrndr.shape.path3D - -/** - * Kotlin/OPENRNDR idiomatic interface to `Delaunay` - */ -class DelaunayTriangulation3D(val points: List) { - val delaunay: Delaunay = Delaunay.from(points.map { it.xy }) - - fun neighbors(pointIndex: Int): Sequence { - return delaunay.neighbors(pointIndex) - } - - fun neighborPoints(pointIndex: Int): List { - return neighbors(pointIndex).map { points[it] }.toList() - } - - fun triangleIndices(): List { - val list = mutableListOf() - for (i in delaunay.triangles.indices step 3) { - list.add( - intArrayOf( - delaunay.triangles[i], - delaunay.triangles[i + 1], - delaunay.triangles[i + 2] - ) - ) - } - return list - } - - fun triangles(filterPredicate: (Int, Int, Int) -> Boolean = { _, _, _ -> true }): MutableList { - val list = mutableListOf() - - for (i in delaunay.triangles.indices step 3) { - val t0 = delaunay.triangles[i] - val t1 = delaunay.triangles[i + 1] - val t2 = delaunay.triangles[i + 2] - - // originally they are defined *counterclockwise* - if (filterPredicate(t2, t1, t0)) { - val p1 = points[t0] - val p2 = points[t1] - val p3 = points[t2] - list.add(Triangle3D(p1, p2, p3)) - } - } - return list - } - - // Inner edges of the delaunay triangulation (without hull) - fun halfedges() = path3D { - for (i in delaunay.halfedges.indices) { - val j = delaunay.halfedges[i] - - if (j < i) continue - val ti = delaunay.triangles[i] - val tj = delaunay.triangles[j] - - moveTo(points[ti]) - lineTo(points[tj]) - } - } - - fun hull() = path3D { - for (h in delaunay.hull) { - moveOrLineTo(points[h]) - } - close() - } - - fun nearest(query: Vector3): Int = delaunay.find(query.x, query.y) - - fun nearestPoint(query: Vector3): Vector3 = points[nearest(query)] -} - -/** - * Computes the Delaunay triangulation for the list of 2D points. - * - * The Delaunay triangulation is a triangulation of a set of points such that - * no point is inside the circumcircle of any triangle. It maximizes the minimum - * angle of all the angles in the triangles, avoiding skinny triangles. - * - * @return A DelaunayTriangulation object representing the triangulation of the given points. - */ -fun List.delaunayTriangulation(): DelaunayTriangulation3D { - return DelaunayTriangulation3D(this) -} diff --git a/android/src/main/java/com/icegps/orx/triangulation/Triangle3D.kt b/android/src/main/java/com/icegps/orx/triangulation/Triangle3D.kt deleted file mode 100644 index 0b840eea..00000000 --- a/android/src/main/java/com/icegps/orx/triangulation/Triangle3D.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.icegps.orx.triangulation - -import org.openrndr.math.Vector3 -import org.openrndr.shape.BezierSegment -import org.openrndr.shape.Path -import org.openrndr.shape.Path3D - -/** - * @author tabidachinokaze - * @date 2025/11/24 - */ -data class Triangle3D( - val x1: Vector3, - val x2: Vector3, - val x3: Vector3, -) : Path { - val path = Path3D.fromPoints(points = listOf(x1, x2, x3), closed = true) - override fun sub(t0: Double, t1: Double): Path = path.sub(t0, t1) - - override val closed: Boolean get() = path.closed - override val empty: Boolean get() = path.empty - override val infinity: Vector3 get() = path.infinity - override val segments: List> get() = path.segments -} \ No newline at end of file diff --git a/icegps-triangulation/build.gradle.kts b/icegps-triangulation/build.gradle.kts index a95692d3..f4d76e90 100644 --- a/icegps-triangulation/build.gradle.kts +++ b/icegps-triangulation/build.gradle.kts @@ -3,11 +3,14 @@ plugins { alias(libs.plugins.kotlin.jvm) } java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlin { compilerOptions { - jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 } } +dependencies { + implementation(project(":math")) +} \ No newline at end of file diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunator.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunator.kt index 0958d1cc..c33ca417 100644 --- a/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunator.kt +++ b/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunator.kt @@ -1,4 +1,4 @@ -package org.openrndr.extra.triangulation +package com.icegps.triangulation import kotlin.math.* diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunay.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunay.kt index 36f8ddcd..22e0a2e2 100644 --- a/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunay.kt +++ b/icegps-triangulation/src/main/java/com/icegps/triangulation/Delaunay.kt @@ -1,8 +1,7 @@ -package org.openrndr.extra.triangulation +package com.icegps.triangulation -import org.openrndr.extra.triangulation.Delaunay.Companion.from -import org.openrndr.math.Vector2 -import org.openrndr.shape.Rectangle +import com.icegps.math.geometry.Vector2D +import com.icegps.triangulation.Delaunay.Companion.from import kotlin.math.cos import kotlin.math.pow import kotlin.math.sin @@ -42,7 +41,7 @@ class Delaunay(val points: DoubleArray) { * * @property points a list of 2D points */ - fun from(points: List): Delaunay { + fun from(points: List): Delaunay { val n = points.size val coords = DoubleArray(n * 2) @@ -74,13 +73,13 @@ class Delaunay(val points: DoubleArray) { init() } - fun neighbors(i:Int) = sequence { + fun neighbors(i: Int) = sequence { val e0 = inedges[i] if (e0 != -1) { var e = e0 var p0 = -1 - loop@do { + loop@ do { p0 = triangles[e] yield(p0) e = if (e % 3 == 2) e - 2 else e + 1 @@ -109,26 +108,28 @@ class Delaunay(val points: DoubleArray) { for (i in 0 until triangles.size step 3) { val a = 2 * triangles[i] val b = 2 * triangles[i + 1] - val c = 2 * triangles[i + 2] + val c = 2 * triangles[i + 2] val coords = points val cross = (coords[c] - coords[a]) * (coords[b + 1] - coords[a + 1]) - - (coords[b] - coords[a]) * (coords[c + 1] - coords[a + 1]) + -(coords[b] - coords[a]) * (coords[c + 1] - coords[a + 1]) if (cross > 1e-10) return false; } return true } - private fun jitter(x:Double, y:Double, r:Double): DoubleArray { - return doubleArrayOf(x + sin(x+y) * r, y + cos(x-y)*r) + + private fun jitter(x: Double, y: Double, r: Double): DoubleArray { + return doubleArrayOf(x + sin(x + y) * r, y + cos(x - y) * r) } + fun init() { if (hull.size > 2 && collinear()) { println("warning: triangulation is collinear") val r = 1E-8 for (i in 0 until points.size step 2) { - val p = jitter(points[i], points[i+1], r) + val p = jitter(points[i], points[i + 1], r) points[i] = p[0] - points[i+1] = p[1] + points[i + 1] = p[1] } delaunator = Delaunator(points) @@ -221,12 +222,4 @@ class Delaunay(val points: DoubleArray) { return c } - - /** - * Generates a Voronoi diagram based on the current Delaunay triangulation and the provided bounds. - * - * @param bounds A rectangle defining the boundaries within which the Voronoi diagram will be generated. - * @return A Voronoi instance representing the resulting Voronoi diagram. - */ - fun voronoi(bounds: Rectangle): Voronoi = Voronoi(this, bounds) } diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/DelaunayTriangulation.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/DelaunayTriangulation.kt index 4f57c9eb..84171771 100644 --- a/icegps-triangulation/src/main/java/com/icegps/triangulation/DelaunayTriangulation.kt +++ b/icegps-triangulation/src/main/java/com/icegps/triangulation/DelaunayTriangulation.kt @@ -1,24 +1,19 @@ -package org.openrndr.extra.triangulation +package com.icegps.triangulation -import org.openrndr.math.Vector2 -import org.openrndr.shape.Rectangle -import org.openrndr.shape.Triangle -import org.openrndr.shape.contour -import org.openrndr.shape.contours +import com.icegps.math.geometry.Vector3D +import com.icegps.math.geometry.toVector2D /** * Kotlin/OPENRNDR idiomatic interface to `Delaunay` */ -class DelaunayTriangulation(val points: List) { - val delaunay: Delaunay = Delaunay.from(points) - - fun voronoiDiagram(bounds: Rectangle) = VoronoiDiagram(this, bounds) +class DelaunayTriangulation(val points: List) { + val delaunay: Delaunay = Delaunay.from(points.map { it.toVector2D() }) fun neighbors(pointIndex: Int): Sequence { return delaunay.neighbors(pointIndex) } - fun neighborPoints(pointIndex: Int): List { + fun neighborPoints(pointIndex: Int): List { return neighbors(pointIndex).map { points[it] }.toList() } @@ -55,30 +50,9 @@ class DelaunayTriangulation(val points: List) { return list } - // Inner edges of the delaunay triangulation (without hull) - fun halfedges() = contours { - for (i in delaunay.halfedges.indices) { - val j = delaunay.halfedges[i] + fun nearest(query: Vector3D): Int = delaunay.find(query.x, query.y) - if (j < i) continue - val ti = delaunay.triangles[i] - val tj = delaunay.triangles[j] - - moveTo(points[ti]) - lineTo(points[tj]) - } - } - - fun hull() = contour { - for (h in delaunay.hull) { - moveOrLineTo(points[h]) - } - close() - } - - fun nearest(query: Vector2): Int = delaunay.find(query.x, query.y) - - fun nearestPoint(query: Vector2): Vector2 = points[nearest(query)] + fun nearestPoint(query: Vector3D): Vector3D = points[nearest(query)] } /** @@ -90,6 +64,6 @@ class DelaunayTriangulation(val points: List) { * * @return A DelaunayTriangulation object representing the triangulation of the given points. */ -fun List.delaunayTriangulation(): DelaunayTriangulation { +fun List.delaunayTriangulation(): DelaunayTriangulation { return DelaunayTriangulation(this) } diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/DoubleDouble.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/DoubleDouble.kt index 477adf04..b668907b 100644 --- a/icegps-triangulation/src/main/java/com/icegps/triangulation/DoubleDouble.kt +++ b/icegps-triangulation/src/main/java/com/icegps/triangulation/DoubleDouble.kt @@ -1,4 +1,4 @@ -package org.openrndr.extra.triangulation +package com.icegps.triangulation import kotlin.math.pow diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/Predicates.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/Predicates.kt index 7b5e129d..ee833cae 100644 --- a/icegps-triangulation/src/main/java/com/icegps/triangulation/Predicates.kt +++ b/icegps-triangulation/src/main/java/com/icegps/triangulation/Predicates.kt @@ -1,4 +1,4 @@ -package org.openrndr.extra.triangulation +package com.icegps.triangulation fun orient2d(bx: Double, by: Double, ax: Double, ay: Double, cx: Double, cy: Double): Double { // (ax,ay) (bx,by) are swapped such that the sign of the determinant is flipped. which is what Delaunator.kt expects. diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/Triangle.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/Triangle.kt new file mode 100644 index 00000000..440593a3 --- /dev/null +++ b/icegps-triangulation/src/main/java/com/icegps/triangulation/Triangle.kt @@ -0,0 +1,13 @@ +package com.icegps.triangulation + +import com.icegps.math.geometry.Vector3D + +/** + * @author tabidachinokaze + * @date 2025/11/26 + */ +data class Triangle( + val x1: Vector3D, + val x2: Vector3D, + val x3: Vector3D, +) diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/Voronoi.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/Voronoi.kt deleted file mode 100644 index bbcc0e7c..00000000 --- a/icegps-triangulation/src/main/java/com/icegps/triangulation/Voronoi.kt +++ /dev/null @@ -1,622 +0,0 @@ -package org.openrndr.extra.triangulation - -import org.openrndr.math.Vector2 -import org.openrndr.shape.Rectangle -import kotlin.math.abs -import kotlin.math.floor -import kotlin.math.sign - -/* -ISC License - -Copyright 2021 Ricardo Matias. - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. -*/ - - -/** - * This is a fast library for computing the Voronoi diagram of a set of two-dimensional points. - * The Voronoi diagram is constructed by connecting the circumcenters of adjacent triangles - * in the Delaunay triangulation. - * - * @description Port of d3-delaunay (JavaScript) library - https://github.com/d3/d3-delaunay - * @property points flat positions' array - [x0, y0, x1, y1..] - * - * @since 9258fa3 - commit - * @author Ricardo Matias - */ -class Voronoi(val delaunay: Delaunay, val bounds: Rectangle) { - private val _circumcenters = DoubleArray(delaunay.points.size * 2) - lateinit var circumcenters: DoubleArray - private set - - val vectors = DoubleArray(delaunay.points.size * 2) - - init { - init() - } - - fun update() { - delaunay.update() - init() - } - - fun init() { - val points = delaunay.points - - if (delaunay.points.isEmpty()) { - return - } - - val triangles = delaunay.triangles - val hull = delaunay.hull - - if (points.size == 2) { - _circumcenters[0] = points[0] - _circumcenters[1] = points[1] - circumcenters = _circumcenters - return - } - - circumcenters = _circumcenters.copyOf(delaunay.triangles.size / 3 * 2) - - // Compute circumcenters - var i = 0 - var j = 0 - - var x: Double - var y: Double - - while (i < triangles.size) { - val t1 = triangles[i] * 2 - val t2 = triangles[i + 1] * 2 - val t3 = triangles[i + 2] * 2 - val x1 = points[t1] - val y1 = points[t1 + 1] - val x2 = points[t2] - val y2 = points[t2 + 1] - val x3 = points[t3] - val y3 = points[t3 + 1] - - val dx = x2 - x1 - val dy = y2 - y1 - val ex = x3 - x1 - val ey = y3 - y1 - val ab = (dx * ey - dy * ex) * 2 - - if (abs(ab) < 1e-9) { - var a = 1e9 - val r = triangles[0] * 2 - a *= sign((points[r] - x1) * ey - (points[r + 1] - y1) * ex) - x = (x1 + x3) / 2 - a * ey - y = (y1 + y3) / 2 + a * ex - } else { - val d = 1 / ab - val bl = dx * dx + dy * dy - val cl = ex * ex + ey * ey - x = x1 + (ey * bl - dy * cl) * d - y = y1 + (dx * cl - ex * bl) * d - } - - circumcenters[j] = x - circumcenters[j + 1] = y - - i += 3 - j += 2 - } - - // Compute exterior cell rays. - var h = hull[hull.size - 1] - var p0: Int - var p1 = h * 4 - var x0: Double - var x1 = points[2 * h] - var y0: Double - var y1 = points[2 * h + 1] - var y01: Double - var x10: Double - - vectors.fill(0.0) - - for (idx in hull.indices) { - h = hull[idx] - p0 = p1 - x0 = x1 - y0 = y1 - p1 = h * 4 - x1 = points[2 * h] - y1 = points[2 * h + 1] - - y01 = y0 - y1 - x10 = x1 - x0 - - vectors[p0 + 2] = y01 - vectors[p1] = y01 - vectors[p0 + 3] = x10 - vectors[p1 + 1] = x10 - } - - } - - - - private fun cell(i: Int): MutableList? { - - - - val inedges = delaunay.inedges - val halfedges = delaunay.halfedges - val triangles = delaunay.triangles - - val e0 = inedges[i] - - if (e0 == -1) return null // coincident point - - val points = mutableListOf() - - var e = e0 - - do { - val t = floor(e / 3.0).toInt() - - points.add(circumcenters[t * 2]) - points.add(circumcenters[t * 2 + 1]) - - e = if (e % 3 == 2) e - 2 else e + 1 // next half edge - - if (triangles[e] != i) break - - e = halfedges[e] - } while (e != e0 && e != -1) - - return points - } - - fun neighbors(i: Int) = sequence { - val ci = clip(i) - if (ci != null) { - for (j in delaunay.neighbors(i)) { - val cj = clip(j) - if (cj != null) { - val li = ci.size - val lj = cj.size - loop@ for (ai in 0 until ci.size step 2) { - for (aj in 0 until cj.size step 2) { - if (ci[ai] == cj[aj] - && ci[ai + 1] == cj[aj + 1] - && ci[(ai + 2) % li] == cj[(aj + lj - 2) % lj] - && ci[(ai + 3) % li] == cj[(aj + lj - 1) % lj] - ) { - yield(j) - break@loop - } - } - } - } - } - } - } - - internal fun clip(i: Int): List? { - // degenerate case (1 valid point: return the box) - if (i == 0 && delaunay.points.size == 2) { - return listOf( - bounds.xmax, - bounds.ymin, - bounds.xmax, - bounds.ymax, - bounds.xmin, - bounds.ymax, - bounds.xmin, - bounds.ymin - ) - } - - val points = cell(i) ?: return null - - val clipVectors = vectors - val v = i * 4 - - val a = !clipVectors[v].isFalsy() - val b = !clipVectors[v + 1].isFalsy() - - return if (a || b) { - this.clipInfinite(i, points, clipVectors[v], clipVectors[v + 1], clipVectors[v + 2], clipVectors[v + 3]) - } else { - this.clipFinite(i, points) - } - } - - private fun clipInfinite( - i: Int, - points: MutableList, - vx0: Double, - vy0: Double, - vxn: Double, - vyn: Double - ): List? { - var P: MutableList? = points.mutableCopyOf() - - P!! - project(P[0], P[1], vx0, vy0)?.let { p -> P!!.add(0, p[1]); P!!.add(0, p[0]) } - project(P[P.size - 2], P[P.size - 1], vxn, vyn)?.let { p -> P!!.add(p[0]); P!!.add(p[1]) } - - P = this.clipFinite(i, P!!) - var n = 0 - if (P != null) { - n = P!!.size - var c0 = -1 - var c1 = edgeCode(P[n - 2], P[n - 1]) - var j = 0 - var n = P.size - while (j < n) { - c0 = c1 - c1 = edgeCode(P[j], P[j + 1]) - if (c0 != 0 && c1 != 0) { - j = edge(i, c0, c1, P, j) - n = P.size - } - j += 2 - } - } else if (this.contains(i, (bounds.xmin + bounds.xmax) / 2.0, (bounds.ymin + bounds.ymax) / 2.0)) { - P = mutableListOf( - bounds.xmin, - bounds.ymin, - bounds.xmax, - bounds.ymin, - bounds.xmax, - bounds.ymax, - bounds.xmin, - bounds.ymax - ) - } - return P - } - - private fun clipFinite(i: Int, points: MutableList): MutableList? { - val n = points.size - - val P = mutableListOf() - var x0: Double - var y0: Double - var x1 = points[n - 2] - var y1 = points[n - 1] - var c0: Int - var c1: Int = regionCode(x1, y1) - var e0: Int? = null - var e1: Int? = 0 - - for (j in 0 until n step 2) { - x0 = x1 - y0 = y1 - x1 = points[j] - y1 = points[j + 1] - c0 = c1 - c1 = regionCode(x1, y1) - - if (c0 == 0 && c1 == 0) { - e0 = e1 - e1 = 0 - - P.add(x1) - P.add(y1) - } else { - var S: DoubleArray? - var sx0: Double - var sy0: Double - var sx1: Double - var sy1: Double - - if (c0 == 0) { - S = clipSegment(x0, y0, x1, y1, c0, c1) - if (S == null) continue - sx0 = S[0] - sy0 = S[1] - sx1 = S[2] - sy1 = S[3] - } else { - S = clipSegment(x1, y1, x0, y0, c1, c0) - if (S == null) continue - sx1 = S[0] - sy1 = S[1] - sx0 = S[2] - sy0 = S[3] - - e0 = e1 - e1 = this.edgeCode(sx0, sy0) - - if (e0 != 0 && e1 != 0) this.edge(i, e0!!, e1, P, P.size) - - P.add(sx0) - P.add(sy0) - } - - e0 = e1 - e1 = this.edgeCode(sx1, sy1); - - if (e0.isTruthy() && e1.isTruthy()) this.edge(i, e0!!, e1, P, P.size); - - P.add(sx1) - P.add(sy1) - } - } - - if (P.isNotEmpty()) { - e0 = e1 - e1 = this.edgeCode(P[0], P[1]) - - if (e0.isTruthy() && e1.isTruthy()) this.edge(i, e0!!, e1!!, P, P.size); - } else if (this.contains(i, (bounds.xmin + bounds.xmax) / 2, (bounds.ymin + bounds.ymax) / 2)) { - return mutableListOf( - bounds.xmax, - bounds.ymin, - bounds.xmax, - bounds.ymax, - bounds.xmin, - bounds.ymax, - bounds.xmin, - bounds.ymin - ) - } else { - return null - } - return P - } - - private fun clipSegment(x0: Double, y0: Double, x1: Double, y1: Double, c0: Int, c1: Int): DoubleArray? { - var nx0: Double = x0 - var ny0: Double = y0 - var nx1: Double = x1 - var ny1: Double = y1 - var nc0: Int = c0 - var nc1: Int = c1 - - while (true) { - if (nc0 == 0 && nc1 == 0) return doubleArrayOf(nx0, ny0, nx1, ny1) - // SHAKY STUFF - if ((nc0 and nc1) != 0) return null - - var x: Double - var y: Double - val c: Int = if (nc0 != 0) nc0 else nc1 - - when { - (c and 0b1000) != 0 -> { - x = nx0 + (nx1 - nx0) * (bounds.ymax - ny0) / (ny1 - ny0) - y = bounds.ymax; - } - (c and 0b0100) != 0 -> { - x = nx0 + (nx1 - nx0) * (bounds.ymin - ny0) / (ny1 - ny0) - y = bounds.ymin - } - (c and 0b0010) != 0 -> { - y = ny0 + (ny1 - ny0) * (bounds.xmax - nx0) / (nx1 - nx0) - x = bounds.xmax - } - else -> { - y = ny0 + (ny1 - ny0) * (bounds.xmin - nx0) / (nx1 - nx0) - x = bounds.xmin; - } - } - - if (nc0 != 0) { - nx0 = x - ny0 = y - nc0 = this.regionCode(nx0, ny0) - } else { - nx1 = x - ny1 = y - nc1 = this.regionCode(nx1, ny1) - } - } - } - - private fun regionCode(x: Double, y: Double): Int { - val xcode = when { - x < bounds.xmin -> 0b0001 - x > bounds.xmax -> 0b0010 - else -> 0b0000 - } - val ycode = when { - y < bounds.ymin -> 0b0100 - y > bounds.ymax -> 0b1000 - else -> 0b0000 - } - return xcode or ycode - } - - - private fun contains(i: Int, x: Double, y: Double): Boolean { - if (x.isNaN() || y.isNaN()) return false - return this.delaunay.step(i, x, y) == i; - } - - private fun edge(i: Int, e0: Int, e1: Int, p: MutableList, j: Int): Int { - var j = j - var e = e0 - loop@ while (e != e1) { - var x: Double = Double.NaN - var y: Double = Double.NaN - - when (e) { - 0b0101 -> { // top-left - e = 0b0100 - continue@loop - } - 0b0100 -> { // top - e = 0b0110 - x = bounds.xmax - y = bounds.ymin - } - 0b0110 -> { // top-right - e = 0b0010 - continue@loop - } - 0b0010 -> { // right - e = 0b1010 - x = bounds.xmax - y = bounds.ymax - } - 0b1010 -> { // bottom-right - e = 0b1000 - continue@loop - } - 0b1000 -> { // bottom - e = 0b1001 - x = bounds.xmin - y = bounds.ymax - } - 0b1001 -> { // bottom-left - e = 0b0001 - continue@loop - } - 0b0001 -> { // left - e = 0b0101 - x = bounds.xmin - y = bounds.ymin - } - } - - if (((j < p.size && (p[j] != x)) || ((j + 1) < p.size && p[j + 1] != y)) && contains(i, x, y)) { - require(!x.isNaN()) - require(!y.isNaN()) - p.add(j, y) - p.add(j, x) - j += 2 - } else if (j >= p.size && contains(i, x, y)) { - require(!x.isNaN()) - require(!y.isNaN()) - p.add(x) - p.add(y) - j += 2 - } - } - - if (p.size > 4) { - var idx = 0 - var n = p.size - while (idx < n) { - val j = (idx + 2) % p.size - val k = (idx + 4) % p.size - - if ((p[idx] == p[j] && p[j] == p[k]) - || (p[idx + 1] == p[j + 1] && p[j + 1] == p[k + 1]) - ) { - // SHAKY - p.removeAt(j) - p.removeAt(j) - idx -= 2 - n -= 2 - } - idx += 2 - } - } - return j - } - - private fun project(x0: Double, y0: Double, vx: Double, vy: Double): Vector2? { - var t = Double.POSITIVE_INFINITY - var c: Double - var x = Double.NaN - var y = Double.NaN - - // top - if (vy < 0) { - if (y0 <= bounds.ymin) return null - c = (bounds.ymin - y0) / vy - - if (c < t) { - t = c - - y = bounds.ymin - x = x0 + t * vx - } - } else if (vy > 0) { // bottom - if (y0 >= bounds.ymax) return null - c = (bounds.ymax - y0) / vy - - if (c < t) { - t = c - - y = bounds.ymax - x = x0 + t * vx - } - } - // right - if (vx > 0) { - if (x0 >= bounds.xmax) return null - c = (bounds.xmax - x0) / vx - - if (c < t) { - t = c - - x = bounds.xmax - y = y0 + t * vy - } - } else if (vx < 0) { // left - if (x0 <= bounds.xmin) return null - c = (bounds.xmin - x0) / vx - - if (c < t) { - t = c - - x = bounds.xmin - y = y0 + t * vy - } - } - - if (x.isNaN() || y.isNaN()) return null - - return Vector2(x, y) - } - - private fun edgeCode(x: Double, y: Double): Int { - val xcode = when (x) { - bounds.xmin -> 0b0001 - bounds.xmax -> 0b0010 - else -> 0b0000 - } - val ycode = when (y) { - bounds.ymin -> 0b0100 - bounds.ymax -> 0b1000 - else -> 0b0000 - } - return xcode or ycode - } - -} - -private fun Int?.isTruthy(): Boolean { - return (this != null && this != 0) -} - -private fun List.mutableCopyOf(): MutableList { - val original = this - return mutableListOf().apply { addAll(original) } -} - -private val Rectangle.xmin: Double - get() = this.corner.x - -private val Rectangle.xmax: Double - get() = this.corner.x + width - -private val Rectangle.ymin: Double - get() = this.corner.y - -private val Rectangle.ymax: Double - get() = this.corner.y + height - -private fun Double?.isFalsy() = this == null || this == -0.0 || this == 0.0 || isNaN() - diff --git a/icegps-triangulation/src/main/java/com/icegps/triangulation/typealias.kt b/icegps-triangulation/src/main/java/com/icegps/triangulation/typealias.kt deleted file mode 100644 index 2a696c30..00000000 --- a/icegps-triangulation/src/main/java/com/icegps/triangulation/typealias.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.icegps.triangulation - -/** - * @author tabidachinokaze - * @date 2025/11/24 - */ -typealias Vector2 = Vector \ No newline at end of file diff --git a/math/src/main/java/com/icegps/math/geometry/VectorsDouble.kt b/math/src/main/java/com/icegps/math/geometry/VectorsDouble.kt index c8981634..41fb9665 100644 --- a/math/src/main/java/com/icegps/math/geometry/VectorsDouble.kt +++ b/math/src/main/java/com/icegps/math/geometry/VectorsDouble.kt @@ -121,6 +121,13 @@ data class Vector2D(val x: Double, val y: Double) : IsAlmostEquals { fun distanceTo(x: Int, y: Int): Double = this.distanceTo(x.toDouble(), y.toDouble()) fun distanceTo(that: Vector2D): Double = distanceTo(that.x, that.y) + /** Calculates the squared Euclidean distance to [other]. */ + fun squaredDistanceTo(other: Vector2D): Double { + val dx = other.x - x + val dy = other.y - y + return dx * dx + dy * dy + } + infix fun cross(that: Vector2D): Double = crossProduct(this, that) infix fun dot(that: Vector2D): Double = ((this.x * that.x) + (this.y * that.y)) @@ -195,6 +202,8 @@ data class Vector2D(val x: Double, val y: Double) : IsAlmostEquals { /** DOWN using screen coordinates as reference (0, +1) */ val DOWN_SCREEN = Vector2D(0.0, +1.0) + val INFINITY = Vector2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY) + inline operator fun invoke(x: Number, y: Number): Vector2D = Vector2D(x.toDouble(), y.toDouble()) //inline operator fun invoke(x: Float, y: Float): Vector2D = Vector2D(x.toDouble(), y.toDouble()) diff --git a/settings.gradle.kts b/settings.gradle.kts index 284341f6..60f9c7f9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,3 @@ -import org.gradle.internal.os.OperatingSystem - rootProject.name = "orx" @@ -36,7 +34,7 @@ dependencyResolutionManagement { versionCatalogs { // We use a regex to get the openrndr version from the primary catalog as there is no public Gradle API to parse catalogs. val regEx = Regex("^openrndr[ ]*=[ ]*(?:\\{[ ]*require[ ]*=[ ]*)?\"(.*)\"[ ]*(?:\\})?", RegexOption.MULTILINE) - val openrndrVersion = regEx.find(File(rootDir,"gradle/libs.versions.toml").readText())?.groupValues?.get(1) ?: error("can't find openrndr version") + val openrndrVersion = regEx.find(File(rootDir, "gradle/libs.versions.toml").readText())?.groupValues?.get(1) ?: error("can't find openrndr version") create("sharedLibs") { from("org.openrndr:openrndr-dependency-catalog:$openrndrVersion") } @@ -130,4 +128,5 @@ include(":android") include(":math") include(":desktop") include(":icegps-common") -include(":icegps-shared") \ No newline at end of file +include(":icegps-shared") +include(":icegps-triangulation") \ No newline at end of file