Rescaling
This guide provides practical examples and detailed usage patterns for rescaling transformations in Crater. For the mathematical theory, see Rescaling Transformations.
Available Rescaling Functions
Hyperbolic Tangent Family
Standard Tanh:
- Domain:
- Range:
- Properties: Smooth function, preserves sign, symmetric about origin
- Parameters: controls transition steepness
Scaled Tanh:
- Domain:
- Range:
- Properties: Configurable center point and half-range
#![allow(unused)] fn main() { use crater::csg::prelude::*; use crater::csg::rescale::RescaleScheme; use burn::backend::wgpu::WgpuDevice; use burn::backend::wgpu::Wgpu; fn example_tanh_rescaling() { // Standard tanh: maps to (-1, 1) let device = WgpuDevice::default(); let field = Field3D::<Wgpu>::sphere(2.0, device).into_isosurface(0.0); let tanh_field = field.clone().rescale(RescaleScheme::Tanh { k: 2.0 }); // Scaled tanh: maps to (3, 7) with center at 5 let scaled_field = field.rescale(RescaleScheme::ScaledTanh { center: 5.0, scale: 2.0, k: 1.0, }); } }
Logistic (Sigmoid) Family
Standard Sigmoid:
- Domain:
- Range:
- Properties: Smooth function, monotonically increasing, asymptotic bounds
- Numerical Stability: Implementation uses different formulas for positive/negative inputs
Scaled Sigmoid:
- Domain:
- Range:
- Properties: Configurable minimum and range
Arctangent Family
Standard Arctan:
- Domain:
- Range:
- Properties: Smooth function, preserves sign, linear near origin for small
Scaled Arctan:
- Domain:
- Range:
Error Function
Error Function:
- Domain:
- Range:
- Properties: Smooth function, Gaussian-like transition, preserves sign
- Implementation: High-quality approximation using
Soft Clipping
Soft Clip:
- Domain:
- Range:
- Properties: Preserves sign, linear for small inputs, asymptotic bounds
- Continuity: Continuous everywhere but not differentiable at when
Practical Examples
Example 1: Normalizing Distance Fields
use crater::csg::prelude::*; use crater::csg::rescale::RescaleScheme; use burn::backend::wgpu::WgpuDevice; use burn::backend::wgpu::Wgpu; fn main() { let device = WgpuDevice::default(); // Create a sphere distance field let sphere = Field3D::<Wgpu>::sphere(2.0, device); // Normalize to (-1, 1) range with tanh let normalized = sphere.rescale(RescaleScheme::Tanh { k: 0.5 }); }
Example 2: Creating Probability-Like Fields
use crater::csg::prelude::*; use crater::csg::rescale::RescaleScheme; use burn::backend::wgpu::WgpuDevice; use burn::backend::wgpu::Wgpu; fn main() { let device = WgpuDevice::default(); // Create a sphere distance field let sphere = Field3D::<Wgpu>::sphere(2.0, device); // Convert distance field to probability-like values in (0, 1) let probability_field = sphere.rescale(RescaleScheme::Sigmoid { k: 2.0 }); // Values near the surface (distance ≈ 0) map to ≈ 0.5 // Negative distances (inside) map to values < 0.5 // Positive distances (outside) map to values > 0.5 }
Example 3: Custom Range Mapping
use crater::csg::prelude::*; use crater::csg::rescale::RescaleScheme; use burn::backend::wgpu::WgpuDevice; use burn::backend::wgpu::Wgpu; fn main() { let device = WgpuDevice::default(); // Map field values to engineering units [0, 100] let field = Field3D::<Wgpu>::sphere(2.0, device).into_isosurface(0.0); let engineering_field = field.rescale(RescaleScheme::ScaledSigmoid { min: 0.0, range: 100.0, k: 1.0, }); }
Example 4: Large-Scale Numerical Stability
This example demonstrates how rescaling prevents numerical failures with large geometric features:
use crater::csg::prelude::*; use crater::analysis::prelude::*; use burn::backend::wgpu::WgpuDevice; use burn::backend::wgpu::Wgpu; use burn::backend::Autodiff; use burn::prelude::*; fn main() { let device = WgpuDevice::default(); // Create a very large sphere (radius = 100 units) // Without rescaling, distance values would range from -∞ to +∞ let large_sphere = Field3D::<Autodiff<Wgpu>>::sphere(100.0, device.clone()).into_isosurface(0.0); // Apply tanh rescaling to bound values to (-1, 1) // k = 0.01 provides smooth transition around the surface let rescaled_sphere = large_sphere.rescale(RescaleScheme::Tanh { k: 0.01 }); // Test points at various distances from center let test_points = [ [0.0, 0.0, 0.0], // Center: distance = -100 → tanh(-1) ≈ -0.76 [50.0, 0.0, 0.0], // Halfway: distance = -50 → tanh(-0.5) ≈ -0.46 [100.0, 0.0, 0.0], // Surface: distance = 0 → tanh(0) = 0 [150.0, 0.0, 0.0], // Outside: distance = 50 → tanh(0.5) ≈ 0.46 [200.0, 0.0, 0.0], // Far outside: distance = 100 → tanh(1) ≈ 0.76 ]; let results = rescaled_sphere.evaluate(Tensor::<Autodiff<Wgpu>, 2, Float>::from_data(test_points, &device)); // All values are guaranteed to be in (-1, 1) // Ray casting and other algorithms converge reliably // No overflow or underflow issues with extreme distances // Ray casting that would fail with unbounded fields now works let rays = Rays::new_from_slices( &[[110.0, 0.0, 0.0], [90.0, 0.0, 0.0]], &[[-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]], device ); let intersections = rescaled_sphere.region().ray_cast( rays, &Algebra::default(), RayCastAlgorithm::Analytical ); // ✓ Successful intersection finding with bounded field values }
Why This Example Matters: Large distance values (±100 units) would cause floating-point precision issues in iterative algorithms
Parameter Selection Guidelines
Steepness Parameter
- Small (< 1): Gradual transition, nearly linear near origin
- Large (> 5): Sharp transition, step-function-like behavior
- : Balanced transition suitable for most applications
Range Parameters
- Choose based on downstream requirements
- Consider numerical precision of target system
- Ensure compatibility with other field operations