Remove allocation

This commit is contained in:
Michał Chodzikiewicz 2020-12-19 15:09:32 +01:00
parent 74a07353e3
commit c23edcb93c
4 changed files with 98 additions and 89 deletions

View file

@ -9,20 +9,19 @@ use embedded_graphics_simulator::{
OutputSettingsBuilder OutputSettingsBuilder
}; };
use embedded_plots::{ use embedded_plots::curve::{PlotPoint, CurvePoints};
CurvePoints,
PlotPoint
};
fn main() -> Result<(), core::convert::Infallible> { fn main() -> Result<(), core::convert::Infallible> {
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(480, 272)); let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(480, 272));
let data = vec![ let data = vec![
PlotPoint{x: 100,y: 100}, PlotPoint{x: 0,y: 0},
PlotPoint{x: 150,y: 100}, PlotPoint{x: 1,y: 1},
PlotPoint{x: 200,y: 200}]; PlotPoint{x: 2,y: 1},
PlotPoint{x: 3,y: 0},
];
CurvePoints::new(data.as_slice()) CurvePoints::new(data.as_slice())
.into_drawable_curve(&(100..200),&(100..200),Point{x: 00, y: 0}, Point{x:480,y:272},RgbColor::WHITE) .into_drawable_curve(&(0..3),&(0..1),&Point{x: 20, y: 20}, &Point{x:450,y:250},RgbColor::WHITE)
.draw(&mut display)?; .draw(&mut display)?;
let output_settings = OutputSettingsBuilder::new() let output_settings = OutputSettingsBuilder::new()

46
src/curve.rs Normal file
View file

@ -0,0 +1,46 @@
use core::ops::{Range};
use crate::range_conv::Scalable;
use crate::drawable_curve::DrawableCurve;
use embedded_graphics::prelude::*;
pub struct PlotPoint {
pub x: i32,
pub y: i32,
}
pub struct CurvePoints<'a>{
points: &'a [PlotPoint],
}
impl<'a> CurvePoints<'a> {
pub fn new(points: &'a [PlotPoint]) -> CurvePoints {
CurvePoints{points}
}
pub fn into_drawable_curve<C>(self, x_range: &'a Range<i32>, y_range: &'a Range<i32>, top_left : &'a Point, bottom_right: &'a Point, color: C) -> DrawableCurve<C,impl Iterator<Item=Point> + 'a>
where C: PixelColor
{
assert!(top_left.x < bottom_right.x);
assert!(top_left.y < bottom_right.y);
assert!(!x_range.is_empty());
assert!(!y_range.is_empty());
let it = self.points.iter()
.map(move |p| Point{
x: p.x.scale_between_ranges(x_range,&Range{start: top_left.x, end: bottom_right.x}),
y: p.y.scale_between_ranges(y_range,&Range{start: bottom_right.y, end: top_left.y}),
});
DrawableCurve::new(it,color)
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

42
src/drawable_curve.rs Normal file
View file

@ -0,0 +1,42 @@
use embedded_graphics::drawable::{Drawable, Pixel};
use embedded_graphics::DrawTarget;
use embedded_graphics::geometry::Point;
use embedded_graphics::pixelcolor::{PixelColor};
use embedded_graphics::primitives::{Line, Primitive};
use embedded_graphics::style::PrimitiveStyle;
pub struct DrawableCurve<C, I>
where
I: Iterator<Item=Point>,
{
scaled_data: I,
color: C,
}
impl<'a, C,I> DrawableCurve<C,I>
where
C: PixelColor,
I: Iterator<Item=Point>,
{
pub fn new(data: I,color : C) -> DrawableCurve<C,I> {
DrawableCurve {
scaled_data: data,
color,
}
}
}
impl<'a, C,I> Drawable<C> for DrawableCurve<C,I>
where C: PixelColor,
I: Iterator<Item=Point>,
{
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), <D as DrawTarget<C>>::Error> {
let style = PrimitiveStyle::with_stroke(self.color,2);
let mut iter = self.scaled_data.into_iter();
let mut prev = iter.next().unwrap();
for point in iter {
Line::new(prev,point).into_styled(style).draw(display)?;
prev = point;
}
Ok(())
}
}

View file

@ -1,83 +1,5 @@
// #![no_std] #![no_std]
pub mod curve;
pub mod drawable_curve;
mod range_conv; mod range_conv;
use embedded_graphics::drawable::{Drawable};
use embedded_graphics::DrawTarget;
use embedded_graphics::geometry::Point;
use embedded_graphics::pixelcolor::{PixelColor};
use embedded_graphics::primitives::{Line, Primitive};
use embedded_graphics::style::PrimitiveStyle;
use crate::range_conv::Scalable;
use core::ops::{Range};
pub struct PlotPoint {
pub x: i32,
pub y: i32,
}
pub struct CurvePoints<'a>{
points: &'a [PlotPoint],
}
impl<'a> CurvePoints<'a> {
pub fn new(points: &'a [PlotPoint]) -> CurvePoints {
CurvePoints{points}
}
pub fn into_drawable_curve<C>(self, x_range: &Range<i32>, y_range: &Range<i32>, top_left : Point, bottom_right: Point, color: C) -> DrawableCurve<C>
where C: PixelColor
{
assert!(top_left.x < bottom_right.x);
assert!(top_left.y < bottom_right.y);
assert!(!x_range.is_empty());
assert!(!y_range.is_empty());
let vec = self.points.iter()
.map(|p| Point{
x: p.x.scale_between_ranges(x_range,&Range{start: top_left.x.into(), end: bottom_right.x.into()}).into(),
y: p.y.scale_between_ranges(y_range,&Range{start: top_left.y.into(), end: bottom_right.y.into()}).into(),
})
.collect();
DrawableCurve::new(vec,color)
}
}
pub struct DrawableCurve<C>
{
scaled_and_pos_data: Vec<Point>,
color: C,
}
impl<'a, C> DrawableCurve<C>
where C: PixelColor
{
pub fn new(data: Vec<Point>,color : C) -> DrawableCurve<C> {
println!("data: {:?}",data);
DrawableCurve {
scaled_and_pos_data: data,
color,
}
}
}
impl<'a, C> Drawable<C> for DrawableCurve<C>
where C: PixelColor
{
fn draw<D: DrawTarget<C>>(self, display: &mut D) -> Result<(), <D as DrawTarget<C>>::Error> {
let style = PrimitiveStyle::with_stroke(self.color,2);
for i in 1..self.scaled_and_pos_data.len() {
Line::new(self.scaled_and_pos_data[i-1],self.scaled_and_pos_data[i]).into_styled(style).draw(display)?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}