diff options
author | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-28 11:54:52 +0800 |
---|---|---|
committer | Jovansonlee Cesar <ivanceras@gmail.com> | 2022-09-28 11:54:52 +0800 |
commit | 80f1c92f83a56fea9dfc9aa8f52df27ac4e5d72c (patch) | |
tree | f4de263144a3bfd8c19b06181c3edd16822946ef | |
parent | 1d179168f429c2dcf257feeed57c3a99d624b083 (diff) |
feat: implement THREE_QUARTERS_ARC circles
-rw-r--r-- | packages/svgbob/src/buffer/cell_buffer/span.rs | 20 | ||||
-rw-r--r-- | packages/svgbob/src/buffer/fragment_buffer/fragment/arc.rs | 13 | ||||
-rw-r--r-- | packages/svgbob/src/map/circle_map.rs | 101 | ||||
-rw-r--r-- | packages/svgbob/src/map/circle_map/test_circle_map.rs | 8 | ||||
-rw-r--r-- | packages/svgbob/test_data/circles_generated.bob | 836 |
5 files changed, 977 insertions, 1 deletions
diff --git a/packages/svgbob/src/buffer/cell_buffer/span.rs b/packages/svgbob/src/buffer/cell_buffer/span.rs index fde515e..b584a9f 100644 --- a/packages/svgbob/src/buffer/cell_buffer/span.rs +++ b/packages/svgbob/src/buffer/cell_buffer/span.rs @@ -8,7 +8,7 @@ use crate::{ }, fragment, map::{circle_map, UNICODE_FRAGMENTS}, - Cell, Fragment, Merge, Settings, + Cell, Fragment, Merge, Point, Settings, }; use itertools::Itertools; use std::{ @@ -79,6 +79,15 @@ impl Span { this } + fn top_left(&self) -> Cell { + let bounds = self.bounds().expect("must have bounds"); + bounds.0 + } + + pub fn localize_point(&self, point: Point) -> Point { + self.top_left().localize_point(point) + } + /// returns the top_left most cell which aligns the top most and the left most cell. pub(crate) fn bounds(&self) -> Option<(Cell, Cell)> { if let Some((min_y, max_y)) = @@ -180,6 +189,15 @@ impl Span { FragmentSpan::new(self.clone(), circle.into()); accepted.push(circle_frag_span); un_endorsed_span + } else if let Some((three_quarters_arc, un_endorsed_span)) = + circle_map::endorse_three_quarters_arc_span(&self) + { + let three_quarters_arc = + three_quarters_arc.absolute_position(top_left); + let three_quarters_arc_frag_span = + FragmentSpan::new(self.clone(), three_quarters_arc.into()); + accepted.push(three_quarters_arc_frag_span); + un_endorsed_span } else if let Some((half_arc, un_endorsed_span)) = circle_map::endorse_half_arc_span(&self) { diff --git a/packages/svgbob/src/buffer/fragment_buffer/fragment/arc.rs b/packages/svgbob/src/buffer/fragment_buffer/fragment/arc.rs index 2f09b3b..133220d 100644 --- a/packages/svgbob/src/buffer/fragment_buffer/fragment/arc.rs +++ b/packages/svgbob/src/buffer/fragment_buffer/fragment/arc.rs @@ -34,6 +34,19 @@ impl Arc { arc } + pub(crate) fn major(start: Point, end: Point, radius: f32) -> Self { + let mut arc = Arc { + start, + end, + radius, + major_flag: true, + sweep_flag: false, + rotation_flag: false, + }; + arc.sort_reorder_end_points(); + arc + } + /// check if this arcs to point a, b /// disregarding radius pub(crate) fn arcs_to(&self, a: Point, b: Point) -> bool { diff --git a/packages/svgbob/src/map/circle_map.rs b/packages/svgbob/src/map/circle_map.rs index 20b324f..69f15cd 100644 --- a/packages/svgbob/src/map/circle_map.rs +++ b/packages/svgbob/src/map/circle_map.rs @@ -720,6 +720,69 @@ lazy_static! { }) ); + 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)], + is_shared_x: circle_art.is_shared_x(), + is_shared_y: circle_art.is_shared_y(), + }) + }) + ); + pub static ref FLATTENED_QUARTER_ARC_SPAN: BTreeMap<DiameterArc, (Arc,Span)> = BTreeMap::from_iter( @@ -748,6 +811,19 @@ lazy_static! { }) ); + 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, + }, + arc_span.clone() + ) + }) + }) + ); + } #[derive(Default, Hash, PartialEq, Eq)] @@ -856,6 +932,31 @@ pub fn endorse_half_arc_span(search: &Span) -> Option<(&Arc, Span)> { }) } +pub fn endorse_three_quarters_arc_span(search: &Span) -> Option<(&Arc, Span)> { + FLATTENED_THREE_QUARTERS_ARC_SPAN.iter().rev().find_map( + |(_diameter, (arc, span))| { + let search_localized = search.clone().localize(); + let (matched, unmatched) = is_subset_of(span, &search_localized); + if matched { + let unmatched_cell_chars = search + .iter() + .enumerate() + .filter_map(|(i, cell_char)| { + if unmatched.contains(&i) { + Some(*cell_char) + } else { + None + } + }) + .collect::<Vec<_>>(); + Some((arc, Span::from(unmatched_cell_chars))) + } else { + None + } + }, + ) +} + /// returns true if all the contacts in subset is in big_set /// This also returns the indices of big_set that are not found in the subset fn is_subset_of<T: PartialEq>( diff --git a/packages/svgbob/src/map/circle_map/test_circle_map.rs b/packages/svgbob/src/map/circle_map/test_circle_map.rs index c6abc7b..df878d9 100644 --- a/packages/svgbob/src/map/circle_map/test_circle_map.rs +++ b/packages/svgbob/src/map/circle_map/test_circle_map.rs @@ -26,6 +26,14 @@ fn show_circles() { println!(); println!(); } + println!("THREE QUARTERS ARCS:"); + for (diameter, (arc, span)) in FLATTENED_THREE_QUARTERS_ARC_SPAN.iter() { + println!("diameter: {}", diameter.diameter); + println!(); + println!("{}", span); + println!(); + println!(); + } panic!(); } diff --git a/packages/svgbob/test_data/circles_generated.bob b/packages/svgbob/test_data/circles_generated.bob index 6a2b3db..b86c24a 100644 --- a/packages/svgbob/test_data/circles_generated.bob +++ b/packages/svgbob/test_data/circles_generated.bob @@ -1544,3 +1544,839 @@ diameter: 22 _.' .....-' + +THREE QUARTER ARCS: +diameter: 4 + + ,-. +( ) + `- + + +diameter: 4 + + ,- +( ) + `-' + + +diameter: 4 + + -. +( ) + `-' + + +diameter: 4 + + ,-. +( ) + -' + + +diameter: 5 + + .--. +( ) + `- + + +diameter: 5 + + .- +( ) + `--' + + +diameter: 5 + + -. +( ) + `--' + + +diameter: 5 + + .--. +( ) + -' + + +diameter: 6 + + _ + .' '. +( ) + `._ + + +diameter: 6 + + _ + .' +( ) + `._.' + + +diameter: 6 + + _ + '. +( ) + `._.' + + +diameter: 6 + + _ + .' '. +( ) + _.' + + +diameter: 7 + + __ + ,' '. +( ) + `._ + + +diameter: 7 + + _ + ,' +( ) + `.__.' + + +diameter: 7 + + _ + '. +( ) + `.__.' + + +diameter: 7 + + __ + ,' '. +( ) + _.' + + +diameter: 8 + + ___ + ,' '. +( ) + `. + `- + + +diameter: 8 + + __ + ,' +( ) + `. .' + `-' + + +diameter: 8 + + __ + '. +( ) + `. .' + `-' + + +diameter: 8 + + ___ + ,' '. +( ) + .' + -' + + +diameter: 9 + + ___ + ,' `. +/ \ +\ + `.__ + + +diameter: 9 + + __ + ,' +/ +\ / + `.___.' + + +diameter: 9 + + __ + `. + \ +\ / + `.___.' + + +diameter: 9 + + ___ + ,' `. +/ \ + / + __.' + + +diameter: 10 + + ____ + ,' `. +/ \ +\ + `.__ + + +diameter: 10 + + __ + ,' +/ +\ / + `.____.' + + +diameter: 10 + + __ + `. + \ +\ / + `.____.' + + +diameter: 10 + + ____ + ,' `. +/ \ + / + __.' + + +diameter: 11 + + ____ + .' `. + / \ +( ) + \ + `.__ + + +diameter: 11 + + __ + .' + / +( ) + \ / + `.____.' + + +diameter: 11 + + __ + `. + \ +( ) + \ / + `.____.' + + +diameter: 11 + + ____ + .' `. + / \ +( ) + / + __.' + + +diameter: 12 + + _____ + ,' `. + / \ +( ) + \ + `.___ + + +diameter: 12 + + ___ + ,' + / +( ) + \ / + `._____.' + + +diameter: 12 + + ___ + `. + \ +( ) + \ / + `._____.' + + +diameter: 12 + + _____ + ,' `. + / \ +( ) + / + ___.' + + +diameter: 13 + + ______ + ,' `. + / \ +| | +| + \ + `.___ + + +diameter: 13 + + ___ + ,' + / +| +| | + \ / + `.______.' + + +diameter: 13 + + ___ + `. + \ + | +| | + \ / + `.______.' + + +diameter: 13 + + ______ + ,' `. + / \ +| | + | + / + ___.' + + +diameter: 14 + + _______ + ,' `. + / \ +| | +| + \ + `.____ + + +diameter: 14 + + ____ + ,' + / +| +| | + \ / + `._______.' + + +diameter: 14 + + ____ + `. + \ + | +| | + \ / + `._______.' + + +diameter: 14 + + _______ + ,' `. + / \ +| | + | + / + ____.' + + +diameter: 15 + + ________ + ,' `. + / \ +| | +| | +| + \ + `.____ + + +diameter: 15 + + ____ + ,' + / +| +| | +| | + \ / + `.________.' + + +diameter: 15 + + ____ + `. + \ + | +| | +| | + \ / + `.________.' + + +diameter: 15 + + ________ + ,' `. + / \ +| | +| | + | + / + ____.' + + +diameter: 16 + + __-----__ + ,' `. + / \ +| | +| | +| + \ + `. + `---- + + +diameter: 16 + + __--- + ,' + / +| +| | +| | + \ / + `. .' + `-------' + + +diameter: 16 + + ---__ + `. + \ + | +| | +| | + \ / + `. .' + `-------' + + +diameter: 16 + + __-----__ + ,' `. + / \ +| | +| | + | + / + .' + ----' + + +diameter: 17 + + .--------. + ,' `. + / \ +| | +| | +| + \ + `. + `---- + + +diameter: 17 + + .---- + ,' + / +| +| | +| | + \ / + `. .' + `--------' + + +diameter: 17 + + ----. + `. + \ + | +| | +| | + \ / + `. .' + `--------' + + +diameter: 17 + + .--------. + ,' `. + / \ +| | +| | + | + / + .' + ----' + + +diameter: 18 + + _.-'''''-._ + ,' `. + / \ +. . +| | +| | +| + \ + `._ + '-... + + +diameter: 18 + + _.-''' + ,' + / +. +| +| | +| | + \ / + `._ _.' + '-.....-' + + +diameter: 18 + + '''-._ + `. + \ + . + | +| | +| | + \ / + `._ _.' + '-.....-' + + +diameter: 18 + + _.-'''''-._ + ,' `. + / \ +. . +| | +| | + | + / + _.' + ...-' + + +diameter: 19 + + _.-''''''-._ + ,' `. + / \ +. . +| | +| | +| + \ + `._ + '-... + + +diameter: 19 + + _.-''' + ,' + / +. +| +| | +| | + \ / + `._ _.' + '-......-' + + +diameter: 19 + + '''-._ + `. + \ + . + | +| | +| | + \ / + `._ _.' + '-......-' + + +diameter: 19 + + _.-''''''-._ + ,' `. + / \ +. . +| | +| | + | + / + _.' + ...-' + + +diameter: 20 + + _.-'''''''-._ + ,' `. + / \ +. . +| | +| | +| + \ + `._ + '-.... + + +diameter: 20 + + _.-'''' + ,' + / +. +| +| | +| | + \ / + `._ _.' + '-.......-' + + +diameter: 20 + + ''''-._ + `. + \ + . + | +| | +| | + \ / + `._ _.' + '-.......-' + + +diameter: 20 + + _.-'''''''-._ + ,' `. + / \ +. . +| | +| | + | + / + _.' + ....-' + + +diameter: 21 + + _.-''''''''-._ + ,' `. + / \ +. . +| | +| | +| +| + \ + `._ + '-.... + + +diameter: 21 + + _.-'''' + ,' + / +. +| +| | +| | +| | + \ / + `._ _.' + '-........-' + + +diameter: 21 + + ''''-._ + `. + \ + . + | +| | +| | +| | + \ / + `._ _.' + '-........-' + + +diameter: 21 + + _.-''''''''-._ + ,' `. + / \ +. . +| | +| | + | + | + / + _.' + ....-' + + +diameter: 22 + + _.-'''''''''-._ + ,' `. + / \ +. . +| | +| | +| +| + \ + `._ + '-..... + + +diameter: 22 + + _.-''''' + ,' + / +. +| +| | +| | +| | + \ / + `._ _.' + '-.........-' + + +diameter: 22 + + '''''-._ + `. + \ + . + | +| | +| | +| | + \ / + `._ _.' + '-.........-' + + +diameter: 22 + + _.-'''''''''-._ + ,' `. + / \ +. . +| | +| | + | + | + / + _.' + .....-' |