use std::ops::{Add, Mul}; use map_editor_lib::util::BezierCurve; use color_eyre::Result; use crossterm::event; use ratatui::Frame; use ratatui::style::{Color, Stylize}; use ratatui::layout::{Constraint, Layout, Rect}; use ratatui::symbols::Marker; use ratatui::text::{Line as TextLine, Span}; use ratatui::widgets::canvas::{Canvas, Line, Points}; #[test] fn curve_test_full() -> Result<()> { color_eyre::install()?; ratatui::run(|terminal| loop { terminal.draw(render)?; if event::read()?.is_key_press() { break Ok(()); } }) } /// Render the UI with a canvas widget. fn render(frame: &mut Frame) { let vertical = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).spacing(1); let horizontal = Layout::horizontal([Constraint::Percentage(100)]).spacing(1); let [top, main] = frame.area().layout(&vertical); let [area] = main.layout(&horizontal); let title = TextLine::from_iter([ Span::from("Canvas Widget").bold(), Span::from(" (Press 'q' to quit)"), ]); frame.render_widget(title.centered(), top); render_canvas(frame, area); } /// Renders the canvas widget with various shapes and a map. pub fn render_canvas(frame: &mut Frame, area: Rect) { let sample_t = vec![ 0.0, 0.2, 0.4, 0.6, 0.8, 1.0, ]; let curve = BezierCurve::new(vec![ Point::new(-50.0, -50.0), Point::new(-50.0, 50.0), Point::new(50.0, 50.0), ]); let canvas = Canvas::default() .x_bounds([-180.0, 180.0]) .y_bounds([-90.0, 90.0]) .marker(Marker::Braille) .paint(|ctx| { ctx.draw(&Points::new(&[ (-50.0, -50.0), (-50.0, 50.0), (50.0, 50.0), ], Color::Black)); // sample_t.windows(2) // .map_while(|a| { // curve.fetch_point(a[0]).zip(curve.fetch_point(a[1])) // }) // .for_each(|(x, y)| { // ctx.draw(&Line::new(x.x, x.y, y.x, y.y, Color::Blue)); // }); }); frame.render_widget(canvas, area); } const EPSILON: f64 = 1e-6; #[derive(Clone, Copy)] struct Point { x: f64, y: f64, } impl Point { pub fn new(x: f64, y: f64) -> Self { Self { x, y } } } impl Add for Point { type Output = Self; fn add(self, rhs: Self) -> Self { Self { x: self.x + rhs.x, y: self.y + rhs.y } } } impl Mul for Point { type Output = Self; fn mul(self, rhs: f64) -> Self { Self { x: self.x * rhs, y: self.y * rhs } } }