///|
/// Difference between distorted and ideal normalized image coordinates.
pub fn distortion_displacement(
point : @core.Point2,
distortion : Distortion,
) -> @core.Vec2 {
let distorted = distort_point(point, distortion)
@core.Vec2::new(x=distorted.x - point.x, y=distorted.y - point.y)
}
///|
pub fn distortion_displacement_field(
points : ArrayView[@core.Point2],
distortion : Distortion,
) -> Array[@core.Vec2] {
let result : Array[@core.Vec2] = []
for point in points {
result.push(distortion_displacement(point, distortion))
}
result
}
///|
pub fn distortion_magnitude_field(
points : ArrayView[@core.Point2],
distortion : Distortion,
) -> Array[Double] {
let result : Array[Double] = []
for displacement in distortion_displacement_field(points, distortion) {
result.push(displacement.norm())
}
result
}
///|
pub fn distortion_rms(
points : ArrayView[@core.Point2],
distortion : Distortion,
) -> Double {
let values = distortion_magnitude_field(points, distortion)
if values.length() == 0 {
0.0
} else {
let mut sum = 0.0
for value in values {
sum += value * value
}
(sum / values.length().to_double()).sqrt()
}
}
///|
pub fn distortion_max(
points : ArrayView[@core.Point2],
distortion : Distortion,
) -> Double {
let mut result = 0.0
for value in distortion_magnitude_field(points, distortion) {
result = result.max(value)
}
result
}
///|
pub fn distortion_is_negligible(
points : ArrayView[@core.Point2],
distortion : Distortion,
tolerance : Double,
) -> Bool {
distortion_max(points, distortion) <= tolerance
}
///|
pub fn distortion_radial_profile(
radii : ArrayView[Double],
distortion : Distortion,
) -> Array[Double] {
let result : Array[Double] = []
for radius in radii {
let squared = radius * radius
result.push(
distortion.k1 * squared +
distortion.k2 * squared * squared +
distortion.k3 * squared * squared * squared,
)
}
result
}
///|
pub fn distortion_corrected_radii(
radii : ArrayView[Double],
distortion : Distortion,
) -> Array[Double] {
let result : Array[Double] = []
for i in 0.. Double {
(distortion.k1 * distortion.k1 +
distortion.k2 * distortion.k2 +
distortion.p1 * distortion.p1 +
distortion.p2 * distortion.p2 +
distortion.k3 * distortion.k3).sqrt()
}
///|
pub fn blend_distortion(
a : Distortion,
b : Distortion,
amount : Double,
) -> Distortion {
let t = amount.max(0.0).min(1.0)
Distortion::brown_conrady(
k1=a.k1 * (1.0 - t) + b.k1 * t,
k2=a.k2 * (1.0 - t) + b.k2 * t,
p1=a.p1 * (1.0 - t) + b.p1 * t,
p2=a.p2 * (1.0 - t) + b.p2 * t,
k3=a.k3 * (1.0 - t) + b.k3 * t,
)
}
///|
pub fn distortion_parameter_distance(a : Distortion, b : Distortion) -> Double {
distortion_parameter_norm(blend_distortion(a, b, 0.0)) +
distortion_parameter_norm(blend_distortion(a, b, 1.0)) -
2.0 * distortion_parameter_norm(blend_distortion(a, b, 0.5))
}