Revert "修复"

This reverts commit f185acd76c.
qdj
邱德佳 7 months ago
parent 394658142d
commit 02192f1f22

@ -179,140 +179,93 @@ impl TryFrom<&LwPolyline> for Arc {
impl Arc { impl Arc {
/// 从DXF LwPolyline实体创建Arc支持自定义颜色 /// 从DXF LwPolyline实体创建Arc支持自定义颜色
pub fn try_from_lwpolyline_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Result<Self, String> { pub fn try_from_lwpolyline_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Result<Self, String> {
// 检查顶点数量必须是2个顶点才能形成圆弧
if lwpolyline.vertices.len() != 2 { if lwpolyline.vertices.len() != 2 {
return Err(format!( return Err(format!("Arc conversion requires exactly 2 vertices, got {}", lwpolyline.vertices.len()));
"Arc conversion requires exactly 2 vertices, got {}",
lwpolyline.vertices.len()
));
} }
let v1 = &lwpolyline.vertices[0]; let v1 = &lwpolyline.vertices[0];
let v2 = &lwpolyline.vertices[1]; let v2 = &lwpolyline.vertices[1];
if v1.bulge.abs() <= f64::EPSILON { // 检查第一个顶点是否有bulge值
if v1.bulge == 0.0 {
return Err("No bulge value found for arc conversion".to_string()); return Err("No bulge value found for arc conversion".to_string());
} }
let style = if lwpolyline.thickness > 0.1 { // 计算弦长和中点
format!( let chord_length = ((v2.x - v1.x).powi(2) + (v2.y - v1.y).powi(2)).sqrt();
"line-style:normal;line-weight:normal;filling:none;color:{}", let mid_x = (v1.x + v2.x) / 2.0;
color.display_rgb() let mid_y = (v1.y + v2.y) / 2.0;
)
} else if lwpolyline.constant_width > 1.0 {
format!(
"line-style:normal;line-weight:hight;filling:none;color:{}",
color.display_rgb()
)
} else {
format!(
"line-style:normal;line-weight:thin;filling:none;color:{}",
color.display_rgb()
)
};
Arc::from_bulge_segment((v1.x, v1.y), (v2.x, v2.y), v1.bulge, style) // 根据bulge值计算圆弧参数
} // bulge = tan(angle/4)其中angle是圆弧的包含角
} let bulge = v1.bulge;
let included_angle = 4.0 * bulge.atan(); // 圆弧包含角(弧度)
impl Arc { // 计算半径
/// 通过两个端点与 bulge 值生成圆弧 let radius = chord_length / (2.0 * (included_angle / 2.0).sin());
pub fn from_bulge_segment(
start: (f64, f64),
end: (f64, f64),
bulge: f64,
style: String,
) -> Result<Self, String> {
if bulge.abs() <= f64::EPSILON {
return Err("Bulge value too small to construct an arc".into());
}
let chord_dx = end.0 - start.0; // 计算圆心位置
let chord_dy = end.1 - start.1; // 弦的方向向量
let chord_length = (chord_dx * chord_dx + chord_dy * chord_dy).sqrt(); let chord_dx = v2.x - v1.x;
if chord_length <= f64::EPSILON { let chord_dy = v2.y - v1.y;
return Err("Arc chord length too small".into());
}
let half_angle = 2.0 * bulge.atan();
let sin_half = (half_angle).sin();
if sin_half.abs() <= f64::EPSILON {
return Err("Arc sweep too small".into());
}
let radius = (chord_length / (2.0 * sin_half)).abs();
let mid_x = (start.0 + end.0) / 2.0;
let mid_y = (start.1 + end.1) / 2.0;
// 弦的垂直方向向左旋转90度
let perp_dx = -chord_dy; let perp_dx = -chord_dy;
let perp_dy = chord_dx; let perp_dy = chord_dx;
let perp_length = (perp_dx * perp_dx + perp_dy * perp_dy).sqrt(); let perp_length = (perp_dx * perp_dx + perp_dy * perp_dy).sqrt();
if perp_length <= f64::EPSILON {
return Err("Cannot determine arc normal".into());
}
// 标准化垂直向量
let unit_perp_x = perp_dx / perp_length; let unit_perp_x = perp_dx / perp_length;
let unit_perp_y = perp_dy / perp_length; let unit_perp_y = perp_dy / perp_length;
let center_offset = radius * half_angle.cos();
let (center_x, center_y) = if bulge > 0.0 { // 计算圆心到弦中点的距离
( let center_distance = radius * (included_angle / 2.0).cos();
mid_x + center_offset * unit_perp_x,
mid_y + center_offset * unit_perp_y, // 根据bulge的符号确定圆心位置
) let center_x = if bulge > 0.0 {
mid_x + center_distance * unit_perp_x
} else {
mid_x - center_distance * unit_perp_x
};
let center_y = if bulge > 0.0 {
mid_y + center_distance * unit_perp_y
} else { } else {
( mid_y - center_distance * unit_perp_y
mid_x - center_offset * unit_perp_x,
mid_y - center_offset * unit_perp_y,
)
}; };
// QET 使用 y 轴向下的坐标系 // 计算起始角度和结束角度
let center_y_qet = -center_y; let start_angle = (v1.y - center_y).atan2(v1.x - center_x);
let start_y_qet = -start.1; let end_angle = (v2.y - center_y).atan2(v2.x - center_x);
let end_y_qet = -end.1;
let mut start_angle = // 将弧度转换为度数
(start_y_qet - center_y_qet).atan2(start.0 - center_x).to_degrees(); let mut start_angle_deg = start_angle.to_degrees();
let mut end_angle = (end_y_qet - center_y_qet).atan2(end.0 - center_x).to_degrees(); let mut end_angle_deg = end_angle.to_degrees();
let normalize = |mut angle: f64| { // 标准化角度到0-360度范围
while angle < 0.0 { if start_angle_deg < 0.0 {
angle += 360.0; start_angle_deg += 360.0;
} }
while angle >= 360.0 { if end_angle_deg < 0.0 {
angle -= 360.0; end_angle_deg += 360.0;
} }
angle
};
start_angle = normalize(start_angle);
end_angle = normalize(end_angle);
let ccw_sweep = (end_angle - start_angle).rem_euclid(360.0);
let cw_sweep = (start_angle - end_angle).rem_euclid(360.0);
let (start_angle, sweep) = if bulge < 0.0
&& ccw_sweep > 180.0
&& cw_sweep > f64::EPSILON
&& cw_sweep < ccw_sweep
{
(end_angle, cw_sweep)
} else {
(start_angle, ccw_sweep)
};
if sweep <= f64::EPSILON { // 计算角度跨度
return Err("Arc sweep too small".into()); let arc_angle = included_angle.to_degrees().abs();
}
// 创建Arc对象
Ok(Arc { Ok(Arc {
x: center_x - radius, x: center_x - radius, // 边界框左上角x坐标
y: center_y_qet - radius, y: -center_y - radius, // 边界框左上角y坐标y轴翻转
width: radius * 2.0, width: radius * 2.0, // 边界框宽度
height: radius * 2.0, height: radius * 2.0, // 边界框高度
start: start_angle, start: start_angle_deg, // 起始角度(度)
angle: sweep, angle: arc_angle, // 圆弧角度跨度(度)
style, style: if lwpolyline.thickness > 0.1 {
format!("line-style:normal;line-weight:normal;filling:none;color:{}", color.display_rgb())
} else {
format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
},
antialias: false, antialias: false,
}) })
} }

@ -955,56 +955,8 @@ impl<'a> ObjectsBuilder<'a> {
} }
Ok(Objects::Group(decomposed_objects)) Ok(Objects::Group(decomposed_objects))
} else if lwpolyline
.vertices
.iter()
.any(|vertex| vertex.bulge.abs() > 1e-10)
{
let mut decomposed_objects =
polygon::decompose_lwpolyline_segments_with_color(lwpolyline, color);
if decomposed_objects.is_empty() {
let mut poly: Polygon =
Polygon::from_lwpolyline_with_color(lwpolyline, color);
poly.update_line_style(&update_line_style);
poly.scale(self.scale_fact.x, self.scale_fact.y);
for cord in &mut poly.coordinates {
cord.x += self.offset.x;
cord.y -= self.offset.y;
}
Ok(Objects::Polygon(poly))
} else {
for obj in &mut decomposed_objects {
match obj {
Objects::Arc(ref mut arc) => {
arc.update_line_style(&update_line_style);
if let Some(w) = lw {
arc.update_line_weight(w);
}
arc.scale(self.scale_fact.x, self.scale_fact.y);
arc.x += self.offset.x;
arc.y -= self.offset.y;
}
Objects::Line(ref mut line) => {
line.update_line_style(&update_line_style);
line.scale(self.scale_fact.x, self.scale_fact.y);
line.x1 += self.offset.x;
line.y1 -= self.offset.y;
line.x2 += self.offset.x;
line.y2 -= self.offset.y;
}
_ => {}
}
}
Ok(Objects::Group(decomposed_objects))
}
} else { } else {
let mut poly: Polygon = let mut poly: Polygon = Polygon::from_lwpolyline_with_color(lwpolyline, color);
Polygon::from_lwpolyline_with_color(lwpolyline, color);
// 根据line_type_name更新线型样式 // 根据line_type_name更新线型样式
poly.update_line_style(&update_line_style); poly.update_line_style(&update_line_style);
@ -1851,11 +1803,6 @@ enum TextEntity<'a> {
// ACI 转换为 HexColor // ACI 转换为 HexColor
fn aci_to_hex_color(aci: u8) -> HexColor { fn aci_to_hex_color(aci: u8) -> HexColor {
if aci == 7 {
// ACI 7 在 CAD 中根据背景切换黑/白,在 QET 中固定为黑色避免不可见
return HexColor::rgb(0, 0, 0);
}
let (r, g, b) = aci_to_rgb(aci); let (r, g, b) = aci_to_rgb(aci);
HexColor::rgb(r, g, b) HexColor::rgb(r, g, b)
} }

@ -324,7 +324,6 @@ pub fn decompose_rounded_rectangle(lwpolyline: &LwPolyline) -> Vec<super::Object
pub fn decompose_rounded_rectangle_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Vec<super::Objects> { pub fn decompose_rounded_rectangle_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Vec<super::Objects> {
let mut objects = Vec::new(); let mut objects = Vec::new();
let vertices = &lwpolyline.vertices; let vertices = &lwpolyline.vertices;
let arc_style = format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb());
for i in 0..vertices.len() { for i in 0..vertices.len() {
let current = &vertices[i]; let current = &vertices[i];
@ -332,28 +331,15 @@ pub fn decompose_rounded_rectangle_with_color(lwpolyline: &LwPolyline, color: He
if current.bulge.abs() > 1e-10 { if current.bulge.abs() > 1e-10 {
// 创建圆弧段 // 创建圆弧段
if let Some(arc) = create_arc_from_bulge_with_style( if let Some(arc) = create_arc_from_bulge_with_color(current.x, current.y, next.x, next.y, current.bulge, color) {
current.x,
current.y,
next.x,
next.y,
current.bulge,
&arc_style,
) {
objects.push(super::Objects::Arc(arc)); objects.push(super::Objects::Arc(arc));
} }
} else { } else {
// 创建直线段 // 创建直线段
let style = if lwpolyline.thickness > 0.5 { let style = if lwpolyline.thickness > 0.5 {
format!( format!("line-style:normal;line-weight:normal;filling:none;color:color:{}", color.display_rgb())
"line-style:normal;line-weight:normal;filling:none;color:{}",
color.display_rgb()
)
} else { } else {
format!( format!("line-style:normal;line-weight:thin;filling:none;color:color:{}", color.display_rgb())
"line-style:normal;line-weight:thin;filling:none;color:{}",
color.display_rgb()
)
}; };
let line = super::Line::new( let line = super::Line::new(
@ -369,103 +355,117 @@ pub fn decompose_rounded_rectangle_with_color(lwpolyline: &LwPolyline, color: He
objects objects
} }
/// 将包含 bulge 的 LwPolyline 拆分为圆弧与直线段 /// 根据bulge值创建圆弧
pub fn decompose_lwpolyline_segments_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Vec<super::Objects> { fn create_arc_from_bulge(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64) -> Option<super::Arc> {
let mut objects = Vec::new(); create_arc_from_bulge_with_color(start_x, start_y, end_x, end_y, bulge, HexColor::BLACK)
let vertex_count = lwpolyline.vertices.len();
if vertex_count < 2 {
return objects;
} }
let base_style = if lwpolyline.thickness > 0.1 { fn create_arc_from_bulge_with_color(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64, color: HexColor) -> Option<super::Arc> {
format!("line-style:normal;line-weight:normal;filling:none;color:{}", color.display_rgb()) if bulge.abs() <= 1e-10 {
} else if lwpolyline.constant_width > 1.0 { return None;
format!("line-style:normal;line-weight:hight;filling:none;color:{}", color.display_rgb()) }
// 计算弦长和中点
let chord_length = ((end_x - start_x).powi(2) + (end_y - start_y).powi(2)).sqrt();
let mid_x = (start_x + end_x) / 2.0;
let mid_y = (start_y + end_y) / 2.0;
// 根据bulge值计算圆弧参数
// bulge = tan(angle/4)其中angle是圆弧的包含角
let included_angle = 4.0 * bulge.atan(); // 圆弧包含角(弧度)
// 计算半径
let radius: f64 = chord_length / (2.0 * (included_angle / 2.0).sin());
// 计算圆心位置
// 弦的方向向量
let chord_dx = end_x - start_x;
let chord_dy = end_y - start_y;
// 弦的垂直方向向左旋转90度
let perp_dx = -chord_dy;
let perp_dy = chord_dx;
let perp_length: f64 = (perp_dx * perp_dx + perp_dy * perp_dy).sqrt();
// 标准化垂直向量
let unit_perp_x = perp_dx / perp_length;
let unit_perp_y = perp_dy / perp_length;
// 计算圆心到中点的距离
let center_distance: f64 = radius * (included_angle / 2.0).cos();
// 根据bulge的符号确定圆心位置
let center_x = if bulge > 0.0 {
mid_x + center_distance * unit_perp_x
} else { } else {
format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb()) mid_x - center_distance * unit_perp_x
}; };
let center_y = if bulge > 0.0 {
let is_closed = (lwpolyline.flags & 1) != 0; mid_y + center_distance * unit_perp_y
let segment_count = if is_closed {
vertex_count
} else { } else {
vertex_count - 1 mid_y - center_distance * unit_perp_y
}; };
for i in 0..segment_count { // 计算起始角度和结束角度
let current = &lwpolyline.vertices[i % vertex_count]; let start_angle = (start_y - center_y).atan2(start_x - center_x);
let next = &lwpolyline.vertices[(i + 1) % vertex_count]; let end_angle = (end_y - center_y).atan2(end_x - center_x);
if (current.x - next.x).abs() < f64::EPSILON && (current.y - next.y).abs() < f64::EPSILON { // 将弧度转换为度数
continue; let mut start_angle_deg: f64 = start_angle.to_degrees();
} let mut end_angle_deg: f64 = end_angle.to_degrees();
if current.bulge.abs() > 1e-10 { // 标准化角度到0-360度范围
match super::Arc::from_bulge_segment( if start_angle_deg < 0.0 {
(current.x, current.y), start_angle_deg += 360.0;
(next.x, next.y),
current.bulge,
base_style.clone(),
) {
Ok(arc) => objects.push(super::Objects::Arc(arc)),
Err(_) => {
let line = super::Line::new(
current.x,
-current.y,
next.x,
-next.y,
base_style.clone(),
);
objects.push(super::Objects::Line(line));
}
}
} else {
let line = super::Line::new(
current.x,
-current.y,
next.x,
-next.y,
base_style.clone(),
);
objects.push(super::Objects::Line(line));
} }
if end_angle_deg < 0.0 {
end_angle_deg += 360.0;
} }
objects // 计算角度跨度
} let arc_angle: f64 = included_angle.to_degrees().abs();
/// 根据bulge值创建圆弧 // // 计算圆弧参数
fn create_arc_from_bulge(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64) -> Option<super::Arc> { // let start_x = start_vertex.x;
super::Arc::from_bulge_segment( // let start_y = -start_vertex.y; // Y轴翻转
(start_x, start_y), // let end_x = end_vertex.x;
(end_x, end_y), // let end_y = -end_vertex.y; // Y轴翻转
bulge,
"line-style:normal;line-weight:thin;filling:none;color:black".to_string(),
)
.ok()
}
fn create_arc_from_bulge_with_color(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64, color: HexColor) -> Option<super::Arc> { // // 弦长
let style = format!( // let chord_length = ((end_x - start_x).powi(2) + (end_y - start_y).powi(2)).sqrt();
"line-style:normal;line-weight:thin;filling:none;color:{}", // if chord_length < 1e-10 {
color.display_rgb() // return None;
); // }
create_arc_from_bulge_with_style(start_x, start_y, end_x, end_y, bulge, &style)
} // // 根据bulge计算圆弧的角度
// let angle = 4.0 * bulge.atan();
fn create_arc_from_bulge_with_style( // // 计算圆弧的半径
start_x: f64, // let radius = chord_length / (2.0 * (angle / 2.0).sin());
start_y: f64,
end_x: f64, // // 计算中点
end_y: f64, // let mid_x = (start_x + end_x) / 2.0;
bulge: f64, // let mid_y = (start_y + end_y) / 2.0;
style: &str,
) -> Option<super::Arc> { // // 计算弦角
super::Arc::from_bulge_segment( // let chord_angle = (end_y - start_y).atan2(end_x - start_x);
(start_x, start_y), // let center_offset = radius * (angle / 2.0).cos();
(end_x, end_y),
bulge, // let center_x = mid_x - center_offset * (chord_angle + std::f64::consts::PI / 2.0).sin();
style.to_string(), // let center_y = mid_y + center_offset * (chord_angle + std::f64::consts::PI / 2.0).cos();
)
.ok() // // 计算起始角度和角度跨度
// let start_angle = (start_y - center_y).atan2(start_x - center_x).to_degrees();
// let angle_span = angle.to_degrees().abs();
let style = format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb());
Some(super::Arc::new(
center_x-radius,
-center_y-radius,
radius.abs() * 2.0,
radius.abs() * 2.0,
start_angle_deg,
arc_angle,
style,
))
} }

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save