diff options
Diffstat (limited to 'packages/svgbob/src/map/circle_map.rs')
-rw-r--r-- | packages/svgbob/src/map/circle_map.rs | 773 |
1 files changed, 491 insertions, 282 deletions
diff --git a/packages/svgbob/src/map/circle_map.rs b/packages/svgbob/src/map/circle_map.rs index 328c656..666f13f 100644 --- a/packages/svgbob/src/map/circle_map.rs +++ b/packages/svgbob/src/map/circle_map.rs @@ -5,7 +5,7 @@ use crate::{ Cell, Point, Settings, }; use indexmap::IndexMap; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use std::{ collections::{BTreeMap, HashMap}, iter::FromIterator, @@ -105,28 +105,28 @@ pub struct ArcSpans { // arrange together in such this way, then endorse them as a circle // Each of these character formation will have a certain circle parameters: center, and radius. // -lazy_static! { - - /// ```ignore - /// 0 1 2 3 4 B C D - /// 0┌─┬─┬─┬─┐ A┌─┬─┬─┬─┐E - /// 1├─┼─┼─┼─┤ │ │ │ │ │ - /// 2├─┼─┼─┼─┤ F├─G─H─I─┤J - /// 3├─┼─┼─┼─┤ │ │ │ │ │ - /// 4├─┼─┼─┼─┤ K├─L─M─N─┤O - /// 5├─┼─┼─┼─┤ │ │ │ │ │ - /// 6├─┼─┼─┼─┤ P├─Q─R─S─┤T - /// 7├─┼─┼─┼─┤ │ │ │ │ │ - /// 8└─┴─┴─┴─┘ U└─┴─┴─┴─┘Y - /// ``` V W X - /// ( - /// art - the ascii art of the circle, the empty space is automatically removed - /// edge_case - where the edge from the left most cell of the circle - /// f32 - how many cell from the left most to the center.x of the circle - /// f32 - how many cell from the top most to the center.y of the circle, - /// Cell - center cell in arc2 - /// ) - static ref CIRCLE_ART_MAP: Vec<(&'static str, Horizontal, f32, f32, Cell)> = + +/// ```ignore +/// 0 1 2 3 4 B C D +/// 0┌─┬─┬─┬─┐ A┌─┬─┬─┬─┐E +/// 1├─┼─┼─┼─┤ │ │ │ │ │ +/// 2├─┼─┼─┼─┤ F├─G─H─I─┤J +/// 3├─┼─┼─┼─┤ │ │ │ │ │ +/// 4├─┼─┼─┼─┤ K├─L─M─N─┤O +/// 5├─┼─┼─┼─┤ │ │ │ │ │ +/// 6├─┼─┼─┼─┤ P├─Q─R─S─┤T +/// 7├─┼─┼─┼─┤ │ │ │ │ │ +/// 8└─┴─┴─┴─┘ U└─┴─┴─┴─┘Y +/// ``` V W X +/// ( +/// art - the ascii art of the circle, the empty space is automatically removed +/// edge_case - where the edge from the left most cell of the circle +/// f32 - how many cell from the left most to the center.x of the circle +/// f32 - how many cell from the top most to the center.y of the circle, +/// Cell - center cell in arc2 +/// ) +static CIRCLE_ART_MAP: Lazy<Vec<(&'static str, Horizontal, f32, f32, Cell)>> = + Lazy::new(|| { vec![ // CIRCLE_0 //center 1,0,k, radius = 0.5 @@ -141,31 +141,46 @@ lazy_static! { // if radius + edge_case has 0.5 then mid, 0.0 then edge // // - (r#" + ( + r#" () - "#, Horizontal::Half, 1.0, 0.5, Cell::new(0,0)), - + "#, + Horizontal::Half, + 1.0, + 0.5, + Cell::new(0, 0), + ), // CIRCLE_1 //center = 1,1,m radius = 1.0 // 3 cell width, (n-1)/2 = (3-1)/2 = 1.0 // vert_mid: half (0.5/1.0) // cx_lies: mid // cy_lies: mid - (r#" + ( + r#" (_) - "#, Horizontal::Half, 1.5, 0.5, Cell::new(1,0)), - + "#, + Horizontal::Half, + 1.5, + 0.5, + Cell::new(1, 0), + ), // CIRCLE_2 //center = 1,1,o radius = 1.5, // 4 cell width, (n-1)/2 = (4-1)/2 = 1.5 // vert_mid: 3/4 (1.5/2.0) // cx_lies: edge // cy_lies: mid - (r#" + ( + r#" __ (__) - "#, Horizontal::Half, 2.0, 1.5, Cell::new(1,1)), - + "#, + Horizontal::Half, + 2.0, + 1.5, + Cell::new(1, 1), + ), // CIRCLE_3 //center: 2,1,m radius: 2.0 // 5 cell width, (n-1)/2 = (5-1)/2 = 2.0 @@ -175,12 +190,17 @@ lazy_static! { // // shared x, if starts at half and offset_center_x * 2.0 is odd // shared y - (r#" + ( + r#" ,-. ( ) `-' - "#, Horizontal::Half, 2.5, 1.5, Cell::new(2,1)), - + "#, + Horizontal::Half, + 2.5, + 1.5, + Cell::new(2, 1), + ), // CIRCLE_4 //center: 2,1,o radius: 2.5 // 6 cell width, (n-1)/2 = (6-1)/2 = 2.5 @@ -190,12 +210,17 @@ lazy_static! { // // no shared x, offset_center_x * 2.0 is even // shared y - (r#" + ( + r#" .--. ( ) `--' - "#, Horizontal::Half, 3.0, 1.5, Cell::new(2,1)), - + "#, + Horizontal::Half, + 3.0, + 1.5, + Cell::new(2, 1), + ), // CIRCLE_5 //center: 3,2,m radius: 3.0 // 7 cell width, (n-1)/2 = (7-1)/2 = 3.0 @@ -205,13 +230,18 @@ lazy_static! { // // shared x // shared y - (r#" + ( + r#" _ .' '. ( ) `._.' - "#, Horizontal::Half, 3.5, 2.5, Cell::new(3,2)), - + "#, + Horizontal::Half, + 3.5, + 2.5, + Cell::new(3, 2), + ), // CIRCLE_6 //center: 3,2,o radius: 3.5 // 8 cell width, (n-1)/2 = (8-1)/2 = 3.5 @@ -221,13 +251,18 @@ lazy_static! { // // no shared x // shared y - (r#" + ( + r#" __ ,' '. ( ) `.__.' - "#, Horizontal::Half, 4.0, 2.5, Cell::new(3,2)), - + "#, + Horizontal::Half, + 4.0, + 2.5, + Cell::new(3, 2), + ), // CIRCLE_7 //center: 4,2,m radius:4.0 // 9 cell width, (n-1)/2 = (9-1)/2 = 4.0 @@ -237,14 +272,19 @@ lazy_static! { // // shared x // shared y - (r#" + ( + r#" ___ ,' '. ( ) `. .' `-' - "#, Horizontal::Half, 4.5, 2.5, Cell::new(4,2)), - + "#, + Horizontal::Half, + 4.5, + 2.5, + Cell::new(4, 2), + ), // circle 8 and up can be divided into 4 quadrants these quadrants can be arcs and can be used as // rounded edge with larger radius for rouded rect // CIRCLE_8 @@ -257,14 +297,19 @@ lazy_static! { // // shared x // no shared y - (r#" + ( + r#" ___ ,' `. / \ \ / `.___.' - "#, Horizontal::LeftEdge, 4.5, 3.0, Cell::new(4,2) ), - + "#, + Horizontal::LeftEdge, + 4.5, + 3.0, + Cell::new(4, 2), + ), // CIRCLE_9 //center: 4,2,y radius: 5.0 //start_edge: true @@ -275,14 +320,19 @@ lazy_static! { // // no shared x, if offset_center_x * 2.0 is even // no shared y, if the offset_center_y * 2.0 is even - (r#" + ( + r#" ____ ,' `. / \ \ / `.____.' - "#, Horizontal::LeftEdge, 5.0, 3.0, Cell::new(4,2)), - + "#, + Horizontal::LeftEdge, + 5.0, + 3.0, + Cell::new(4, 2), + ), // CIRCLE_10 //center:5,3,o radius: 5.5 // 12 cell width, (n-1)/2 = (12-1)/2 = 5.5 @@ -292,15 +342,20 @@ lazy_static! { // // no shared x // shared y - (r#" + ( + r#" ____ .' `. / \ ( ) \ / `.____.' - "#, Horizontal::Half, 6.0, 3.5, Cell::new(5,3)), - + "#, + Horizontal::Half, + 6.0, + 3.5, + Cell::new(5, 3), + ), // CIRCLE_11 //center:6,3,m radius: 6.0 // 13 cell width, (n-1)/2 = (13-1)/2 = 6.0 @@ -310,15 +365,20 @@ lazy_static! { // // shared x // shared y - (r#" + ( + r#" _____ ,' `. / \ ( ) \ / `._____.' - "#, Horizontal::Half, 6.5, 3.5, Cell::new(6,3)), - + "#, + Horizontal::Half, + 6.5, + 3.5, + Cell::new(6, 3), + ), // CIRCLE_12 // center: 6,3,y radius: 6.5 // vert_mid: 4.0/7.0 @@ -327,7 +387,8 @@ lazy_static! { // // no shared x // no shared y - (r#" + ( + r#" ______ ,' `. / \ @@ -335,8 +396,12 @@ lazy_static! { | | \ / `.______.' - "#, Horizontal::Half, 7.0, 4.0, Cell::new(6,3)), - + "#, + Horizontal::Half, + 7.0, + 4.0, + Cell::new(6, 3), + ), // CIRCLE_13 //center: 7,3,w radius: 7.0 //vert_mid: 4.0/7.0 @@ -345,7 +410,8 @@ lazy_static! { // // shared x // no shared y - (r#" + ( + r#" _______ ,' `. / \ @@ -353,9 +419,12 @@ lazy_static! { | | \ / `._______.' - "#, Horizontal::Half, 7.5, 4.0, Cell::new(7,3)), - - + "#, + Horizontal::Half, + 7.5, + 4.0, + Cell::new(7, 3), + ), // CIRCLE_14 //center: 7,4,o radius: 7.5 //vert_mid: 4.5/8.0 @@ -364,7 +433,8 @@ lazy_static! { // // no shared x // shared y - (r#" + ( + r#" ________ ,' `. / \ @@ -373,8 +443,12 @@ lazy_static! { | | \ / `.________.' - "#, Horizontal::Half, 8.0, 4.5, Cell::new(7,4)), - + "#, + Horizontal::Half, + 8.0, + 4.5, + Cell::new(7, 4), + ), // CIRCLE_15 //center: 8,4,m radius: 8.0 //vert_mid: 4.5/9.0 @@ -383,7 +457,8 @@ lazy_static! { // // shared x // shared y - (r#" + ( + r#" __-----__ ,' `. / \ @@ -393,8 +468,12 @@ lazy_static! { \ / `. .' `-------' - "#, Horizontal::Half, 8.5, 4.5, Cell::new(8,4)), - + "#, + Horizontal::Half, + 8.5, + 4.5, + Cell::new(8, 4), + ), // CIRCLE_16 //center: 8,4,o radius: 8.5 // vert_mid: 4.5/9.0 @@ -403,7 +482,8 @@ lazy_static! { // // no shared x // shared y - (r#" + ( + r#" .--------. ,' `. / \ @@ -413,8 +493,12 @@ lazy_static! { \ / `. .' `--------' - "#, Horizontal::Half, 9.0, 4.5, Cell::new(8,4)), - + "#, + Horizontal::Half, + 9.0, + 4.5, + Cell::new(8, 4), + ), // CIRCLE_17 //center:9,5,m radius: 9.0 //vert_mid: 5.5/10.0 @@ -423,7 +507,8 @@ lazy_static! { // // shared x // shared y - (r#" + ( + r#" _.-'''''-._ ,' `. / \ @@ -434,8 +519,12 @@ lazy_static! { \ / `._ _.' '-.....-' - "#, Horizontal::Half, 9.5, 5.5, Cell::new(9,5)), - + "#, + Horizontal::Half, + 9.5, + 5.5, + Cell::new(9, 5), + ), // CIRCLE_18 // center: 9,5,o radius: 9.5 // vert_mid: 5.5/10.0 @@ -445,7 +534,8 @@ lazy_static! { // no shared x // shared y // - (r#" + ( + r#" _.-''''''-._ ,' `. / \ @@ -456,9 +546,12 @@ lazy_static! { \ / `._ _.' '-......-' - "#, Horizontal::Half, 10.0, 5.5, Cell::new(9,5)), - - + "#, + Horizontal::Half, + 10.0, + 5.5, + Cell::new(9, 5), + ), // CIRCLE_19 // center: 10,5,m radius: 10 // vert_mid: 5.5/10.0 @@ -467,7 +560,8 @@ lazy_static! { // // shared x // shared y - (r#" + ( + r#" _.-'''''''-._ ,' `. / \ @@ -478,8 +572,12 @@ lazy_static! { \ / `._ _.' '-.......-' - "#, Horizontal::Half, 10.5, 5.5, Cell::new(10,5)), - + "#, + Horizontal::Half, + 10.5, + 5.5, + Cell::new(10, 5), + ), // CIRCLE_20 // center: 10,5,o radius: 10.5 // vert_mid: 5.5/11.0 @@ -488,7 +586,8 @@ lazy_static! { // // no shared x // shared y - (r#" + ( + r#" _.-''''''''-._ ,' `. / \ @@ -500,8 +599,12 @@ lazy_static! { \ / `._ _.' '-........-' - "#, Horizontal::Half, 11.0, 5.5, Cell::new(10,5)), - + "#, + Horizontal::Half, + 11.0, + 5.5, + Cell::new(10, 5), + ), // CIRCLE_21 // center: 10,5,m radius: 11 // radius = (n-1)/2 = (23-1)/2 = 11 @@ -511,7 +614,8 @@ lazy_static! { // // shared x // shared y - (r#" + ( + r#" _.-'''''''''-._ ,' `. / \ @@ -523,67 +627,82 @@ lazy_static! { \ / `._ _.' '-.........-' - "#, Horizontal::Half, 11.5, 5.5, Cell::new(11, 5)), - - ]; - - - static ref CIRCLE_MAP: Vec<CircleArt> =Vec::from_iter( - CIRCLE_ART_MAP.iter().enumerate().map(|(ndx, (art, edge_case, offset_center_x, offset_center_y,arc2_center))|{ - CircleArt{ + "#, + Horizontal::Half, + 11.5, + 5.5, + Cell::new(11, 5), + ), + ] + }); + +static CIRCLE_MAP: Lazy<Vec<CircleArt>> = Lazy::new(|| { + Vec::from_iter(CIRCLE_ART_MAP.iter().enumerate().map( + |( + ndx, + (art, edge_case, offset_center_x, offset_center_y, arc2_center), + )| { + CircleArt { ascii_art: *art, start_edge: *edge_case, offset_center_x: *offset_center_x, offset_center_y: *offset_center_y, } - - }) - ); - - - /// The fragments for each of the circle - /// Calculate the span and get the group fragments - static ref FRAGMENTS_CIRCLE: Vec<(Vec<Contacts>,Circle)> = Vec::from_iter( - CIRCLE_MAP.iter().map(|circle_art|{ - (circle_art_to_group(circle_art.ascii_art), Circle::new(circle_art.center(), circle_art.radius(), false)) - }) - ); - - /// map of circle spans and their radius - pub static ref DIAMETER_CIRCLE: HashMap<i32,(Point,Span)> = HashMap::from_iter( - CIRCLE_MAP.iter().map(|circle_art|{ + }, + )) +}); + +/// The fragments for each of the circle +/// Calculate the span and get the group fragments +static FRAGMENTS_CIRCLE: Lazy<Vec<(Vec<Contacts>, Circle)>> = Lazy::new(|| { + Vec::from_iter(CIRCLE_MAP.iter().map(|circle_art| { + ( + circle_art_to_group(circle_art.ascii_art), + Circle::new(circle_art.center(), circle_art.radius(), false), + ) + })) +}); + +/// map of circle spans and their radius +pub static DIAMETER_CIRCLE: Lazy<HashMap<i32, (Point, Span)>> = + Lazy::new(|| { + HashMap::from_iter(CIRCLE_MAP.iter().map(|circle_art| { let cb = CellBuffer::from(circle_art.ascii_art); - let mut spans:Vec<Span> = cb.into(); + let mut spans: Vec<Span> = cb.into(); assert_eq!(spans.len(), 1); let span = spans.remove(0).localize(); (circle_art.diameter(), (circle_art.center(), span)) - }) - ); - - /// There is only 1 span per circle, and localized - pub static ref CIRCLES_SPAN: IndexMap<Circle, Span> = IndexMap::from_iter( - CIRCLE_MAP.iter().map(|circle_art|{ - let cb = CellBuffer::from(circle_art.ascii_art); - let mut spans:Vec<Span> = cb.into(); - assert_eq!(spans.len(), 1); - let span = spans.remove(0).localize(); - (Circle::new(circle_art.center(), circle_art.radius(), false), span) - }) - ); - - /// top_left top top_right - /// p2 - /// arc2 | arc1 - /// | - /// left p3----+----- p1 right - /// | - /// arc3 | arc4 - /// p4 - /// bottom_left bottom bottom_right - /// - /// (diameter, quarter arcs) - pub static ref QUARTER_ARC_SPAN: BTreeMap<i32, ArcSpans> = BTreeMap::from_iter( - CIRCLE_MAP.iter().skip(CIRCLES_TO_SKIP_FOR_ARC).map(|circle_art|{ + })) + }); + +/// There is only 1 span per circle, and localized +pub static CIRCLES_SPAN: Lazy<IndexMap<Circle, Span>> = Lazy::new(|| { + IndexMap::from_iter(CIRCLE_MAP.iter().map(|circle_art| { + let cb = CellBuffer::from(circle_art.ascii_art); + let mut spans: Vec<Span> = cb.into(); + assert_eq!(spans.len(), 1); + let span = spans.remove(0).localize(); + ( + Circle::new(circle_art.center(), circle_art.radius(), false), + span, + ) + })) +}); + +/// top_left top top_right +/// p2 +/// arc2 | arc1 +/// | +/// left p3----+----- p1 right +/// | +/// arc3 | arc4 +/// p4 +/// bottom_left bottom bottom_right +/// +/// (diameter, quarter arcs) +pub static QUARTER_ARC_SPAN: Lazy<BTreeMap<i32, ArcSpans>> = Lazy::new(|| { + BTreeMap::from_iter(CIRCLE_MAP.iter().skip(CIRCLES_TO_SKIP_FOR_ARC).map( + |circle_art| { let span = circle_art_to_span(circle_art.ascii_art); let bounds = span.cell_bounds().expect("must have bounds"); let top_left = bounds.top_left(); @@ -601,12 +720,19 @@ lazy_static! { let arc2_center = circle_art.center_cell(); - - let span1_center = Cell::new((center.x.floor() / Cell::width()) as i32, arc2_center.y); + let span1_center = Cell::new( + (center.x.floor() / Cell::width()) as i32, + arc2_center.y, + ); let span2_center = arc2_center; - let span3_center = Cell::new(arc2_center.x, (center.y.floor() / Cell::height()) as i32); - let span4_center = Cell::new((center.x.floor() / Cell::width()) as i32, (center.y.floor() / Cell::height()) as i32); - + let span3_center = Cell::new( + arc2_center.x, + (center.y.floor() / Cell::height()) as i32, + ); + let span4_center = Cell::new( + (center.x.floor() / Cell::width()) as i32, + (center.y.floor() / Cell::height()) as i32, + ); let bounds1 = Cell::rearrange_bound(span1_center, top_right); let bounds2 = Cell::rearrange_bound(top_left, span2_center); @@ -618,8 +744,7 @@ lazy_static! { let span3 = span.extract(bounds3.0, bounds3.1).localize(); let span4 = span.extract(bounds4.0, bounds4.1).localize(); - - let arc1_start = bounds1.0.localize_point(p1); + let arc1_start = bounds1.0.localize_point(p1); let arc1_end = bounds1.0.localize_point(p2); let arc2_start = bounds2.0.localize_point(p2); @@ -637,16 +762,25 @@ lazy_static! { let arc4 = Arc::new(arc4_start, arc4_end, radius); let diameter = circle_art.diameter(); - (diameter, - ArcSpans{ + ( diameter, - arc_spans: vec![(arc1, span1), (arc2, span2), (arc3, span3), (arc4, span4)], - }) - }) - ); + ArcSpans { + diameter, + arc_spans: vec![ + (arc1, span1), + (arc2, span2), + (arc3, span3), + (arc4, span4), + ], + }, + ) + }, + )) +}); - pub static ref HALF_ARC_SPAN: BTreeMap<i32, ArcSpans> = BTreeMap::from_iter( - CIRCLE_MAP.iter().skip(CIRCLES_TO_SKIP_FOR_ARC).map(|circle_art|{ +pub static HALF_ARC_SPAN: Lazy<BTreeMap<i32, ArcSpans>> = Lazy::new(|| { + BTreeMap::from_iter(CIRCLE_MAP.iter().skip(CIRCLES_TO_SKIP_FOR_ARC).map( + |circle_art| { let span = circle_art_to_span(circle_art.ascii_art); let bounds = span.cell_bounds().expect("must have bounds"); @@ -660,10 +794,8 @@ lazy_static! { assert_eq!(top_right.x, bottom_right.x); assert_eq!(bottom_left.y, bottom_right.y); - let center_cell = circle_art.center_cell(); - let center = circle_art.center(); let radius = circle_art.radius(); @@ -672,15 +804,21 @@ lazy_static! { let p3 = Point::new(center.x - radius, center.y); let p4 = Point::new(center.x, center.y + radius); - let arc2_center = center_cell; - - - let span1_center = Cell::new((center.x.floor() / Cell::width()) as i32, arc2_center.y); + let span1_center = Cell::new( + (center.x.floor() / Cell::width()) as i32, + arc2_center.y, + ); let span2_center = arc2_center; - let span3_center = Cell::new(arc2_center.x, (center.y.floor() / Cell::height()) as i32); - let span4_center = Cell::new((center.x.floor() / Cell::width()) as i32, (center.y.floor() / Cell::height()) as i32); + let span3_center = Cell::new( + arc2_center.x, + (center.y.floor() / Cell::height()) as i32, + ); + let span4_center = Cell::new( + (center.x.floor() / Cell::width()) as i32, + (center.y.floor() / Cell::height()) as i32, + ); let top_tangent = Cell::new(top_right.x, span1_center.y); let bottom_tangent = Cell::new(bottom_left.x, span3_center.y); @@ -688,14 +826,25 @@ lazy_static! { let right_tangent = Cell::new(span1_center.x, top_right.y); let bounds_top_half = Cell::rearrange_bound(top_left, top_tangent); - let bounds_bottom_half = Cell::rearrange_bound(bottom_tangent, bottom_right); - let bounds_left_half = Cell::rearrange_bound(left_tangent, bottom_left); - let bounds_right_half = Cell::rearrange_bound(right_tangent, bottom_right); - - let span_top_half = span.extract(bounds_top_half.0, bounds_top_half.1).localize(); - let span_bottom_half = span.extract(bounds_bottom_half.0, bounds_bottom_half.1).localize(); - let span_left_half = span.extract(bounds_left_half.0, bounds_left_half.1).localize(); - let span_right_half = span.extract(bounds_right_half.0, bounds_right_half.1).localize(); + let bounds_bottom_half = + Cell::rearrange_bound(bottom_tangent, bottom_right); + let bounds_left_half = + Cell::rearrange_bound(left_tangent, bottom_left); + let bounds_right_half = + Cell::rearrange_bound(right_tangent, bottom_right); + + let span_top_half = span + .extract(bounds_top_half.0, bounds_top_half.1) + .localize(); + let span_bottom_half = span + .extract(bounds_bottom_half.0, bounds_bottom_half.1) + .localize(); + let span_left_half = span + .extract(bounds_left_half.0, bounds_left_half.1) + .localize(); + let span_right_half = span + .extract(bounds_right_half.0, bounds_right_half.1) + .localize(); let bottom_half_start = bounds_bottom_half.0.localize_point(p3); let bottom_half_end = bounds_bottom_half.0.localize_point(p1); @@ -703,124 +852,184 @@ lazy_static! { let right_half_start = bounds_right_half.0.localize_point(p4); let right_half_end = bounds_right_half.0.localize_point(p2); - let arc_top_half = Arc::new(p1, p3, radius); - let arc_bottom_half = Arc::new(bottom_half_start, bottom_half_end, radius); + let arc_bottom_half = + Arc::new(bottom_half_start, bottom_half_end, radius); let arc_left_half = Arc::new(p2, p4, radius); - let arc_right_half = Arc::new(right_half_start, right_half_end, radius); + let arc_right_half = + Arc::new(right_half_start, right_half_end, radius); let diameter = circle_art.diameter(); - (diameter, - ArcSpans{ + ( diameter, - arc_spans: vec![(arc_top_half, span_top_half), (arc_bottom_half, span_bottom_half), (arc_left_half, span_left_half), (arc_right_half, span_right_half)], - }) - }) - ); - - pub static ref THREE_QUARTERS_ARC_SPAN: BTreeMap<i32, ArcSpans> = BTreeMap::from_iter( - CIRCLE_MAP.iter().skip(CIRCLES_TO_SKIP_FOR_ARC).map(|circle_art|{ - let span = circle_art_to_span(circle_art.ascii_art); - let bounds = span.cell_bounds().expect("must have bounds"); - let top_left = bounds.top_left(); - let bottom_right = bounds.bottom_right(); - let top_right = bounds.top_right(); - let bottom_left = bounds.bottom_left(); - - let center = circle_art.center(); - let radius = circle_art.radius(); - - let p1 = Point::new(center.x + radius, center.y); - let p2 = Point::new(center.x, center.y - radius); - let p3 = Point::new(center.x - radius, center.y); - let p4 = Point::new(center.x, center.y + radius); - - let arc2_center = circle_art.center_cell(); - - - let span1_center = Cell::new((center.x.floor() / Cell::width()) as i32, arc2_center.y); - let span2_center = arc2_center; - let span3_center = Cell::new(arc2_center.x, (center.y.floor() / Cell::height()) as i32); - let span4_center = Cell::new((center.x.floor() / Cell::width()) as i32, (center.y.floor() / Cell::height()) as i32); - - let top_tangent = Cell::new(top_right.x, span1_center.y); - let bottom_tangent = Cell::new(bottom_left.x, span3_center.y); - let left_tangent = Cell::new(span2_center.x, top_left.y); - let right_tangent = Cell::new(span1_center.x, top_right.y); - - - let bounds1 = Cell::rearrange_bound(span1_center, top_right); - let bounds2 = Cell::rearrange_bound(top_left, span2_center); - let bounds3 = Cell::rearrange_bound(bottom_left, span3_center); - let bounds4 = Cell::rearrange_bound(span4_center, bottom_right); - - let span1 = span.extract(bounds1.0, bounds1.1); - let span2 = span.extract(bounds2.0, bounds2.1); - let span3 = span.extract(bounds3.0, bounds3.1); - let span4 = span.extract(bounds4.0, bounds4.1); - - let span_123 = span1.merge_no_check(&span2).merge_no_check(&span3).localize(); - let span_234 = span2.merge_no_check(&span3).merge_no_check(&span4).localize(); - let span_341 = span3.merge_no_check(&span4).merge_no_check(&span1).localize(); - let span_412 = span4.merge_no_check(&span1).merge_no_check(&span2).localize(); - - - let arc_123 = Arc::major(p1, p4, radius); - let arc_234 = Arc::major(p2, p1, radius); - let arc_341 = Arc::major(p3, p2, radius); - let arc_412 = Arc::major(p4, p3, radius); - - let diameter = circle_art.diameter(); - (diameter, - ArcSpans{ - diameter, - arc_spans: vec![(arc_123, span_123), (arc_234, span_234), (arc_341, span_341), (arc_412, span_412)], - }) - }) - ); - - + ArcSpans { + diameter, + arc_spans: vec![ + (arc_top_half, span_top_half), + (arc_bottom_half, span_bottom_half), + (arc_left_half, span_left_half), + (arc_right_half, span_right_half), + ], + }, + ) + }, + )) +}); - pub static ref FLATTENED_QUARTER_ARC_SPAN: BTreeMap<DiameterArc, (Arc,Span)> = BTreeMap::from_iter( - QUARTER_ARC_SPAN.iter().flat_map(|(diameter, arc_spans)|{ - arc_spans.arc_spans.iter().enumerate().map(move|(arc_index, arc_span)|{ - (DiameterArc{ - diameter: *diameter, - arc: arc_index, - }, - arc_span.clone() - ) - }) - }) - ); - - pub static ref FLATTENED_HALF_ARC_SPAN: BTreeMap<DiameterArc, (Arc,Span)> = BTreeMap::from_iter( - HALF_ARC_SPAN.iter().flat_map(|(diameter, arc_spans)|{ - arc_spans.arc_spans.iter().enumerate().map(move|(arc_index, arc_span)|{ - (DiameterArc{ - diameter: *diameter, - arc: arc_index, - }, - arc_span.clone() - ) - }) - }) - ); - - pub static ref FLATTENED_THREE_QUARTERS_ARC_SPAN: BTreeMap<DiameterArc, (Arc,Span)> = BTreeMap::from_iter( - THREE_QUARTERS_ARC_SPAN.iter().flat_map(|(diameter, arc_spans)|{ - arc_spans.arc_spans.iter().enumerate().map(move|(arc_index, arc_span)|{ - (DiameterArc{ - diameter: *diameter, - arc: arc_index, +pub static THREE_QUARTERS_ARC_SPAN: Lazy<BTreeMap<i32, ArcSpans>> = + Lazy::new(|| { + BTreeMap::from_iter( + CIRCLE_MAP + .iter() + .skip(CIRCLES_TO_SKIP_FOR_ARC) + .map(|circle_art| { + let span = circle_art_to_span(circle_art.ascii_art); + let bounds = span.cell_bounds().expect("must have bounds"); + let top_left = bounds.top_left(); + let bottom_right = bounds.bottom_right(); + let top_right = bounds.top_right(); + let bottom_left = bounds.bottom_left(); + + let center = circle_art.center(); + let radius = circle_art.radius(); + + let p1 = Point::new(center.x + radius, center.y); + let p2 = Point::new(center.x, center.y - radius); + let p3 = Point::new(center.x - radius, center.y); + let p4 = Point::new(center.x, center.y + radius); + + let arc2_center = circle_art.center_cell(); + + let span1_center = Cell::new( + (center.x.floor() / Cell::width()) as i32, + arc2_center.y, + ); + let span2_center = arc2_center; + let span3_center = Cell::new( + arc2_center.x, + (center.y.floor() / Cell::height()) as i32, + ); + let span4_center = Cell::new( + (center.x.floor() / Cell::width()) as i32, + (center.y.floor() / Cell::height()) as i32, + ); + + let top_tangent = Cell::new(top_right.x, span1_center.y); + let bottom_tangent = + Cell::new(bottom_left.x, span3_center.y); + let left_tangent = Cell::new(span2_center.x, top_left.y); + let right_tangent = Cell::new(span1_center.x, top_right.y); + + let bounds1 = + Cell::rearrange_bound(span1_center, top_right); + let bounds2 = Cell::rearrange_bound(top_left, span2_center); + let bounds3 = + Cell::rearrange_bound(bottom_left, span3_center); + let bounds4 = + Cell::rearrange_bound(span4_center, bottom_right); + + let span1 = span.extract(bounds1.0, bounds1.1); + let span2 = span.extract(bounds2.0, bounds2.1); + let span3 = span.extract(bounds3.0, bounds3.1); + let span4 = span.extract(bounds4.0, bounds4.1); + + let span_123 = span1 + .merge_no_check(&span2) + .merge_no_check(&span3) + .localize(); + let span_234 = span2 + .merge_no_check(&span3) + |