///|
/// Visibility masks for image-space and depth-space filtering.
pub fn visible_pixels(
size : ImageSize,
pixels : ArrayView[@core.Point2],
) -> Array[Bool] {
let result : Array[Bool] = []
for pixel in pixels {
result.push(
pixel.x >= 0.0 &&
pixel.y >= 0.0 &&
pixel.x < size.width.to_double() &&
pixel.y < size.height.to_double(),
)
}
result
}
///|
pub fn visible_depths(
depths : ArrayView[Double],
minimum : Double,
maximum : Double,
) -> Array[Bool] {
let result : Array[Bool] = []
for depth in depths {
result.push(depth == depth && depth >= minimum && depth <= maximum)
}
result
}
///|
pub fn valid_projection_count(points : ArrayView[@core.Point3]) -> Int {
let mut count = 0
for point in points {
if point.z > 0.000000000001 {
count += 1
}
}
count
}
///|
pub fn front_facing_ratio(points : ArrayView[@core.Point3]) -> Double {
if points.length() == 0 {
0.0
} else {
valid_projection_count(points).to_double() / points.length().to_double()
}
}
///|
pub fn crop_pixels(
pixels : ArrayView[@core.Point2],
size : ImageSize,
) -> Array[@core.Point2] {
let result : Array[@core.Point2] = []
for pixel in pixels {
if pixel.x >= 0.0 &&
pixel.y >= 0.0 &&
pixel.x < size.width.to_double() &&
pixel.y < size.height.to_double() {
result.push(pixel)
}
}
result
}
///|
pub fn clamp_visible_pixel(
pixel : @core.Point2,
size : ImageSize,
) -> @core.Point2 {
@core.Point2::new(
x=pixel.x.max(0.0).min(size.width.to_double() - 1.0),
y=pixel.y.max(0.0).min(size.height.to_double() - 1.0),
)
}
///|
pub fn image_margin(pixel : @core.Point2, size : ImageSize) -> Double {
pixel.x
.min(pixel.y)
.min(size.width.to_double() - 1.0 - pixel.x)
.min(size.height.to_double() - 1.0 - pixel.y)
}