forked from 1b-agent/opencadstudio-upstream
fix(dim): place DIMTAD "above" text by text-up side, not object side
Dimension text vertical placement chose the perpendicular side away from the measured points, so "Above" (DIMTAD 1) flipped to below whenever the dimension line sat on the opposite side of the geometry. Place it on the side the text top points to instead — the perpendicular of the dimension line normalised to read left-to-right — independent of the object. (#144) Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
c5ad13d5c7
commit
ac5d92c0b4
1 file changed
+40
-8
@@ -2599,15 +2599,20 @@ fn text_on_dim_line(
|
||||
dimtix: bool,
|
||||
below: bool,
|
||||
) -> Vector3 {
|
||||
let px = -ay;
|
||||
let py = ax;
|
||||
// Side of the measured points the dimension line sits on (the "above"
|
||||
// side). DIMTAD=4 (below) flips the text to the other side.
|
||||
let off = (defpt.x - first.x) * px + (defpt.y - first.y) * py;
|
||||
let mut perp_sign = if off >= 0.0 { 1.0 } else { -1.0 };
|
||||
if below {
|
||||
perp_sign = -perp_sign;
|
||||
// "Above" (DIMTAD 1) places the text on the side its top points to — the
|
||||
// perpendicular of the dimension line normalised so the text reads
|
||||
// left-to-right (or bottom-to-top when vertical), NOT the side away from
|
||||
// the measured object. Keying the side off the object flipped "above" into
|
||||
// "below" whenever the dimension ran the opposite way. (#144)
|
||||
let (mut nx, mut ny) = (ax, ay);
|
||||
if nx < 0.0 || (nx == 0.0 && ny < 0.0) {
|
||||
nx = -nx;
|
||||
ny = -ny;
|
||||
}
|
||||
let px = -ny;
|
||||
let py = nx;
|
||||
// +perp is "above"; DIMTAD=4 (below) flips to the other side.
|
||||
let perp_sign = if below { -1.0 } else { 1.0 };
|
||||
// Along-axis positions of the extension points relative to the dim line.
|
||||
let t1 = (first.x - defpt.x) * ax + (first.y - defpt.y) * ay;
|
||||
let t2 = (second.x - defpt.x) * ax + (second.y - defpt.y) * ay;
|
||||
@@ -2747,3 +2752,30 @@ fn dimension_text_pos_f64(
|
||||
fn perp_sign_default() -> f64 {
|
||||
1.0
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod dimtad_tests {
|
||||
use super::text_on_dim_line;
|
||||
use acadrust::types::Vector3;
|
||||
|
||||
fn v(x: f64, y: f64) -> Vector3 {
|
||||
Vector3::new(x, y, 0.0)
|
||||
}
|
||||
|
||||
// DIMTAD=Above must place text on the geometric "up" side of a horizontal
|
||||
// dimension whichever way the dimension runs; DIMTAD=Below flips it. (#144)
|
||||
#[test]
|
||||
fn above_is_up_regardless_of_direction() {
|
||||
let (first, second, defpt) = (v(0.0, 10.0), v(20.0, 10.0), v(0.0, 0.0));
|
||||
let perp = 5.0;
|
||||
let fwd =
|
||||
text_on_dim_line(first, second, defpt, 1.0, 0.0, 0, perp, 0.0, 1.0, false, false);
|
||||
let rev =
|
||||
text_on_dim_line(first, second, defpt, -1.0, 0.0, 0, perp, 0.0, 1.0, false, false);
|
||||
assert!(fwd.y > 0.0, "above must be +Y, got {}", fwd.y);
|
||||
assert!(rev.y > 0.0, "above must be +Y even reversed, got {}", rev.y);
|
||||
let below =
|
||||
text_on_dim_line(first, second, defpt, 1.0, 0.0, 0, perp, 0.0, 1.0, false, true);
|
||||
assert!(below.y < 0.0, "below must be -Y, got {}", below.y);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user