fix 7 bugs from research-3 audit across cord-expr, cord-cordic, cord-sdf, cord-decompile, main
This commit is contained in:
parent
97653580e5
commit
10d4b4e893
|
|
@ -33,7 +33,7 @@ impl CORDICProgram {
|
|||
/// from f64 to fixed-point at compile time. Everything else is a
|
||||
/// direct structural mapping.
|
||||
pub fn compile(graph: &TrigGraph, config: &CompileConfig) -> Self {
|
||||
let frac_bits = config.word_bits - 1;
|
||||
let frac_bits = config.word_bits / 2;
|
||||
let to_fixed = |val: f64| -> i64 {
|
||||
(val * (1i64 << frac_bits) as f64).round() as i64
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub struct CORDICEvaluator {
|
|||
|
||||
impl CORDICEvaluator {
|
||||
pub fn new(word_bits: u8) -> Self {
|
||||
let frac_bits = word_bits - 1;
|
||||
let frac_bits = word_bits / 2;
|
||||
let iterations = word_bits;
|
||||
|
||||
// Precompute atan(2^-i) as fixed-point
|
||||
|
|
@ -134,7 +134,7 @@ impl CORDICEvaluator {
|
|||
y = y_new;
|
||||
}
|
||||
|
||||
// Vectoring output: x_final = (1/K) * sqrt(x0^2 + y0^2).
|
||||
// Vectoring output: x converges to (1/K) * sqrt(x0^2 + y0^2).
|
||||
// self.gain stores K (~0.6073). Multiply to recover true magnitude.
|
||||
let magnitude = self.fixed_mul(x, self.gain);
|
||||
|
||||
|
|
@ -203,15 +203,17 @@ impl CORDICEvaluator {
|
|||
let (_, angle) = self.cordic_vectoring(one, vals[*a as usize]);
|
||||
angle
|
||||
}
|
||||
TrigOp::Sinh(a) => self.to_fixed(self.to_float(vals[*a as usize]).sinh()),
|
||||
TrigOp::Cosh(a) => self.to_fixed(self.to_float(vals[*a as usize]).cosh()),
|
||||
TrigOp::Tanh(a) => self.to_fixed(self.to_float(vals[*a as usize]).tanh()),
|
||||
// Phasor-mode CORDIC implementation coming
|
||||
TrigOp::Sinh(_) => unimplemented!("sinh: phasor CORDIC pending"),
|
||||
TrigOp::Cosh(_) => unimplemented!("cosh: phasor CORDIC pending"),
|
||||
TrigOp::Tanh(_) => unimplemented!("tanh: phasor CORDIC pending"),
|
||||
TrigOp::Exp(_) => unimplemented!("exp: phasor CORDIC pending"),
|
||||
TrigOp::Ln(_) => unimplemented!("ln: phasor CORDIC pending"),
|
||||
|
||||
TrigOp::Asinh(a) => self.to_fixed(self.to_float(vals[*a as usize]).asinh()),
|
||||
TrigOp::Acosh(a) => self.to_fixed(self.to_float(vals[*a as usize]).acosh()),
|
||||
TrigOp::Atanh(a) => self.to_fixed(self.to_float(vals[*a as usize]).atanh()),
|
||||
TrigOp::Sqrt(a) => self.fixed_sqrt(vals[*a as usize]),
|
||||
TrigOp::Exp(a) => self.to_fixed(self.to_float(vals[*a as usize]).exp()),
|
||||
TrigOp::Ln(a) => self.to_fixed(self.to_float(vals[*a as usize]).ln()),
|
||||
|
||||
TrigOp::Hypot(a, b) => {
|
||||
let (mag, _) = self.cordic_vectoring(vals[*a as usize], vals[*b as usize]);
|
||||
|
|
|
|||
|
|
@ -236,18 +236,19 @@ fn align_box_axes(
|
|||
Vec3::new(0.0, 0.0, 1.0),
|
||||
];
|
||||
|
||||
// Assign each detected axis to the closest canonical axis
|
||||
// Assign each detected axis to the closest canonical axis (greedy)
|
||||
let mut assignment = [0usize; 3];
|
||||
let mut assigned = [false; 3];
|
||||
let mut src_assigned = [false; 3];
|
||||
let mut dst_assigned = [false; 3];
|
||||
|
||||
for pass in 0..3 {
|
||||
for _ in 0..3 {
|
||||
let mut best_dot = 0.0f64;
|
||||
let mut best_src = 0;
|
||||
let mut best_dst = 0;
|
||||
for src in 0..3 {
|
||||
if assignment[src] != 0 && pass > 0 { continue; }
|
||||
if src_assigned[src] { continue; }
|
||||
for dst in 0..3 {
|
||||
if assigned[dst] { continue; }
|
||||
if dst_assigned[dst] { continue; }
|
||||
let d = axes[src].dot(canonical[dst]).abs();
|
||||
if d > best_dot {
|
||||
best_dot = d;
|
||||
|
|
@ -257,8 +258,8 @@ fn align_box_axes(
|
|||
}
|
||||
}
|
||||
assignment[best_src] = best_dst;
|
||||
assigned[best_dst] = true;
|
||||
let _ = pass;
|
||||
src_assigned[best_src] = true;
|
||||
dst_assigned[best_dst] = true;
|
||||
}
|
||||
|
||||
let mut ordered = [0.0; 3];
|
||||
|
|
|
|||
|
|
@ -384,7 +384,10 @@ impl<'a> ExprParser<'a> {
|
|||
return Ok(self.graph.push(TrigOp::Mul(sq, base)));
|
||||
}
|
||||
}
|
||||
Ok(self.graph.push(TrigOp::Mul(base, exp)))
|
||||
// base^exp = exp(exp * ln(base))
|
||||
let ln_base = self.graph.push(TrigOp::Ln(base));
|
||||
let product = self.graph.push(TrigOp::Mul(exp, ln_base));
|
||||
Ok(self.graph.push(TrigOp::Exp(product)))
|
||||
} else {
|
||||
Ok(base)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ pub(crate) fn tokenize(input: &str) -> Result<(Vec<Token>, Vec<usize>), String>
|
|||
'/' => {
|
||||
chars.next();
|
||||
match chars.peek() {
|
||||
Some('/') | Some('=') => {
|
||||
Some('/') => {
|
||||
while let Some(&c) = chars.peek() {
|
||||
chars.next();
|
||||
if c == '\n' { line += 1; break; }
|
||||
|
|
|
|||
|
|
@ -126,9 +126,7 @@ fn emit_scad(node: &SdfNode, depth: usize, out: &mut String) {
|
|||
|
||||
SdfNode::SmoothUnion { children, k } => {
|
||||
indent(depth, out);
|
||||
let _ = writeln!(out, "// smooth union (k={})", fmt(*k));
|
||||
indent(depth, out);
|
||||
let _ = writeln!(out, "union() {{");
|
||||
let _ = writeln!(out, "smooth_union(k={}) {{", fmt(*k));
|
||||
for c in children {
|
||||
emit_scad(c, depth + 1, out);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ fn cmd_build(input: &std::path::Path, output: Option<PathBuf>, word_bits: u8) ->
|
|||
} else {
|
||||
writer.write_source_scad(&source)?;
|
||||
}
|
||||
writer.write_trig(&graph.to_bytes())?;
|
||||
writer.write_shader(&wgsl)?;
|
||||
writer.write_cordic(&cordic_bytes, word_bits)?;
|
||||
writer.finish()?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue