Revert "修复"

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

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

@ -955,18 +955,10 @@ impl<'a> ObjectsBuilder<'a> {
}
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);
} else {
let mut poly: Polygon = Polygon::from_lwpolyline_with_color(lwpolyline, color);
// 根据line_type_name更新线型样式
poly.update_line_style(&update_line_style);
poly.scale(self.scale_fact.x, self.scale_fact.y);
@ -976,46 +968,6 @@ impl<'a> ObjectsBuilder<'a> {
}
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 {
let mut poly: Polygon =
Polygon::from_lwpolyline_with_color(lwpolyline, color);
// 根据line_type_name更新线型样式
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))
}
}
}
@ -1851,11 +1803,6 @@ enum TextEntity<'a> {
// ACI 转换为 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);
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> {
let mut objects = Vec::new();
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() {
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 let Some(arc) = create_arc_from_bulge_with_style(
current.x,
current.y,
next.x,
next.y,
current.bulge,
&arc_style,
) {
if let Some(arc) = create_arc_from_bulge_with_color(current.x, current.y, next.x, next.y, current.bulge, color) {
objects.push(super::Objects::Arc(arc));
}
} else {
// 创建直线段
let style = if lwpolyline.thickness > 0.5 {
format!(
"line-style:normal;line-weight:normal;filling:none;color:{}",
color.display_rgb()
)
format!("line-style:normal;line-weight:normal;filling:none;color:color:{}", color.display_rgb())
} else {
format!(
"line-style:normal;line-weight:thin;filling:none;color:{}",
color.display_rgb()
)
format!("line-style:normal;line-weight:thin;filling:none;color:color:{}", color.display_rgb())
};
let line = super::Line::new(
@ -369,103 +355,117 @@ pub fn decompose_rounded_rectangle_with_color(lwpolyline: &LwPolyline, color: He
objects
}
/// 将包含 bulge 的 LwPolyline 拆分为圆弧与直线段
pub fn decompose_lwpolyline_segments_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Vec<super::Objects> {
let mut objects = Vec::new();
let vertex_count = lwpolyline.vertices.len();
if vertex_count < 2 {
return objects;
/// 根据bulge值创建圆弧
fn create_arc_from_bulge(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64) -> Option<super::Arc> {
create_arc_from_bulge_with_color(start_x, start_y, end_x, end_y, bulge, HexColor::BLACK)
}
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> {
if bulge.abs() <= 1e-10 {
return None;
}
let base_style = if lwpolyline.thickness > 0.1 {
format!("line-style:normal;line-weight:normal;filling:none;color:{}", color.display_rgb())
} else if lwpolyline.constant_width > 1.0 {
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 {
format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
mid_x - center_distance * unit_perp_x
};
let is_closed = (lwpolyline.flags & 1) != 0;
let segment_count = if is_closed {
vertex_count
let center_y = if bulge > 0.0 {
mid_y + center_distance * unit_perp_y
} 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 next = &lwpolyline.vertices[(i + 1) % vertex_count];
// 计算起始角度和结束角度
let start_angle = (start_y - center_y).atan2(start_x - center_x);
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;
}
if current.bulge.abs() > 1e-10 {
match super::Arc::from_bulge_segment(
(current.x, current.y),
(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));
}
// 将弧度转换为度数
let mut start_angle_deg: f64 = start_angle.to_degrees();
let mut end_angle_deg: f64 = end_angle.to_degrees();
// 标准化角度到0-360度范围
if start_angle_deg < 0.0 {
start_angle_deg += 360.0;
}
if end_angle_deg < 0.0 {
end_angle_deg += 360.0;
}
// 计算角度跨度
let arc_angle: f64 = included_angle.to_degrees().abs();
// // 计算圆弧参数
// let start_x = start_vertex.x;
// let start_y = -start_vertex.y; // Y轴翻转
// let end_x = end_vertex.x;
// let end_y = -end_vertex.y; // Y轴翻转
// // 弦长
// let chord_length = ((end_x - start_x).powi(2) + (end_y - start_y).powi(2)).sqrt();
// if chord_length < 1e-10 {
// return None;
// }
// // 根据bulge计算圆弧的角度
// let angle = 4.0 * bulge.atan();
// // 计算圆弧的半径
// let radius = chord_length / (2.0 * (angle / 2.0).sin());
// // 计算中点
// let mid_x = (start_x + end_x) / 2.0;
// let mid_y = (start_y + end_y) / 2.0;
// // 计算弦角
// let chord_angle = (end_y - start_y).atan2(end_x - start_x);
// let center_offset = radius * (angle / 2.0).cos();
// let center_x = mid_x - center_offset * (chord_angle + std::f64::consts::PI / 2.0).sin();
// let center_y = mid_y + center_offset * (chord_angle + std::f64::consts::PI / 2.0).cos();
// // 计算起始角度和角度跨度
// let start_angle = (start_y - center_y).atan2(start_x - center_x).to_degrees();
// let angle_span = angle.to_degrees().abs();
objects
}
/// 根据bulge值创建圆弧
fn create_arc_from_bulge(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64) -> Option<super::Arc> {
super::Arc::from_bulge_segment(
(start_x, start_y),
(end_x, end_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!(
"line-style:normal;line-weight:thin;filling:none;color:{}",
color.display_rgb()
);
create_arc_from_bulge_with_style(start_x, start_y, end_x, end_y, bulge, &style)
}
fn create_arc_from_bulge_with_style(
start_x: f64,
start_y: f64,
end_x: f64,
end_y: f64,
bulge: f64,
style: &str,
) -> Option<super::Arc> {
super::Arc::from_bulge_segment(
(start_x, start_y),
(end_x, end_y),
bulge,
style.to_string(),
)
.ok()
}
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