Skip to content

Instantly share code, notes, and snippets.

@orllewin
Created January 25, 2022 10:07
Show Gist options
  • Select an option

  • Save orllewin/0f931e02b9e63a32cf78c530099a2439 to your computer and use it in GitHub Desktop.

Select an option

Save orllewin/0f931e02b9e63a32cf78c530099a2439 to your computer and use it in GitHub Desktop.
/**
* Calculates 256 values from a curve to drive a Toolkit LookupTable which uses a byte array with length 256
* eg. for a red channel the zeroth index in the array has value 0 (black), index 255 has value 255 (pure red)
* but... the values returned here are just the ui input mapped to 0 to 255
* @param curveId - the name of the curve, "RED", "GREEN", "BLUE", "LUMI"
* @return FloatArray with values mapped from the ui in range 0 to 255
*/
fun getData(curveId: String): FloatArray{
//The view can have n curves, find the one with the id we want
val curve = curves.find { curve ->
curve.id == curveId
} ?: throw Exception("No curve found with id: $curveId")
val pathMeasure = PathMeasure(curve.path, false)
val sampleCount = 512
val pathSampleLength = pathMeasure.length/sampleCount
val hyp = sqrt((width.toFloat() * width) + (height * height))
val outValues = FloatArray(256)
val screenXSampleLength = width/256f
val coords = floatArrayOf(0f, 0f)
repeat(sampleCount){ index ->
pathMeasure.getPosTan(index * pathSampleLength, coords, null)
//For a point on the curve
val pathX = coords[0]
val pathY = coords[1]
//Find nearest concrete (non-fractional) x value for our target values (width/256)
val screenX = pathX - (pathX % (screenXSampleLength.toInt()))
//Figure out which index in our out array that x value is
val screenValuesIndex = max(0f, (screenX/screenXSampleLength)).toInt()
//Raw screen value (bottom of the screen is low value)
val rawValue = height - pathY
//Adjust raw y value as we're not forcing a square view
val mappedRawValue = map(rawValue, 0f, height.toFloat(), 0f, width.toFloat())
//Output - Input = change the user wants to see
val difference = mappedRawValue - screenX
//LUT range is 0 to 255, max difference possible in the view is half the hypotenuse
val finalValue = map(difference, 0f, hyp/2, 0f, 255.toFloat())
outValues[min(255, screenValuesIndex)] = finalValue
}
return outValues
}
private fun map(value: Float, aStart: Float, aEnd: Float, bStart: Float, bEnd: Float): Float {
return bStart + (bEnd - bStart) * ((value - aStart) / (aEnd - aStart))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment