|
|
@ -22,13 +22,14 @@ |
|
|
//
|
|
|
//
|
|
|
use std::cmp;
|
|
|
use std::cmp;
|
|
|
use std::fmt::{Formatter, Display, Result};
|
|
|
use std::fmt::{Formatter, Display, Result};
|
|
|
|
|
|
use std::ops::{Add, Sub, Div};
|
|
|
use std::sync::mpsc;
|
|
|
use std::sync::mpsc;
|
|
|
|
|
|
|
|
|
pub trait Easel {
|
|
|
pub trait Easel {
|
|
|
//fn canvas(&mut self, width :u16, height :u16) -> Option<&dyn Canvas>;
|
|
|
//fn canvas(&mut self, width :u16, height :u16) -> Option<&dyn Canvas>;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
pub trait Canvas {
|
|
|
|
|
|
|
|
|
pub trait Canvas<T> {
|
|
|
fn init_events(&self);
|
|
|
fn init_events(&self);
|
|
|
fn start_events(&self, tx :mpsc::Sender<i32>);
|
|
|
fn start_events(&self, tx :mpsc::Sender<i32>);
|
|
|
|
|
|
|
|
|
@ -36,65 +37,71 @@ pub trait Canvas { |
|
|
fn height(&self) -> u16;
|
|
|
fn height(&self) -> u16;
|
|
|
|
|
|
|
|
|
fn clear(&mut self);
|
|
|
fn clear(&mut self);
|
|
|
fn draw(&mut self, c :&dyn Drawable, ofs :Coordinate, color :u32);
|
|
|
|
|
|
fn put_text(&self, ofs :Coordinate, s :&str);
|
|
|
|
|
|
|
|
|
fn draw(&mut self, c :&dyn Drawable<T>, ofs :Coordinate<T>, color :u32);
|
|
|
|
|
|
fn put_text(&self, ofs :Coordinate<T>, s :&str);
|
|
|
fn show(&self);
|
|
|
fn show(&self);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
pub trait Drawable {
|
|
|
|
|
|
fn plot(&self) -> Coordinates;
|
|
|
|
|
|
|
|
|
pub trait Drawable<T> {
|
|
|
|
|
|
fn plot(&self) -> Coordinates<T>;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
pub struct Coordinate(pub i32, pub i32);
|
|
|
|
|
|
|
|
|
pub struct Coordinate<T>(pub i32, pub i32, pub T);
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
#[derive(Debug, Clone)]
|
|
|
pub struct Coordinates(pub Vec<Coordinate>);
|
|
|
|
|
|
|
|
|
pub struct Coordinates<T>(pub Vec<Coordinate<T>>);
|
|
|
|
|
|
|
|
|
impl Coordinate {
|
|
|
|
|
|
|
|
|
impl<T> Coordinate<T>
|
|
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
|
|
|
|
|
|
+ Clone + Copy + From<i32> {
|
|
|
// Tail recursive Bresenham line with integer incremental error.
|
|
|
// Tail recursive Bresenham line with integer incremental error.
|
|
|
fn line(self, b :&Self) -> Vec<Self> {
|
|
|
fn line(self, b :&Self) -> Vec<Self> {
|
|
|
fn inner( v :&mut [Coordinate]
|
|
|
|
|
|
|
|
|
fn inner<T>( v :&mut [Coordinate<T>]
|
|
|
, bx :i32, by :i32 |
|
|
, bx :i32, by :i32 |
|
|
, dx :i32, dy :i32 |
|
|
, dx :i32, dy :i32 |
|
|
, sx :i32, sy :i32 |
|
|
, sx :i32, sy :i32 |
|
|
, err :i32) {
|
|
|
|
|
|
let Coordinate(x, y) = v[0];
|
|
|
|
|
|
|
|
|
, dz :T, err :i32)
|
|
|
|
|
|
where T: Add<Output = T> + Copy {
|
|
|
|
|
|
|
|
|
|
|
|
let Coordinate(x, y, z) = v[0];
|
|
|
|
|
|
|
|
|
if x != bx || y != by {
|
|
|
if x != bx || y != by {
|
|
|
let (x, y, err) = match (2*err >= dy, 2*err <= dx) {
|
|
|
|
|
|
(true, false) => (x + sx, y, err + dy),
|
|
|
|
|
|
(false, true) => ( x, y + sy, err + dx),
|
|
|
|
|
|
_ => (x + sx, y + sy, err + dx + dy ),
|
|
|
|
|
|
|
|
|
let (x, y, z, err) = match (2*err >= dy, 2*err <= dx) {
|
|
|
|
|
|
(true, false) => (x + sx, y, z + dz, err + dy ),
|
|
|
|
|
|
(false, true) => ( x, y + sy, z + dz, err + dx ),
|
|
|
|
|
|
_ => (x + sx, y + sy, z + dz, err + dx + dy ),
|
|
|
};
|
|
|
};
|
|
|
v[1] = Coordinate(x, y);
|
|
|
|
|
|
inner(&mut v[1..], bx, by, dx, dy, sx, sy, err);
|
|
|
|
|
|
|
|
|
v[1] = Coordinate(x, y, z);
|
|
|
|
|
|
inner(&mut v[1..], bx, by, dx, dy, sx, sy, dz, err);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
let Coordinate(ax, ay) = self;
|
|
|
|
|
|
let Coordinate(bx, by) = *b;
|
|
|
|
|
|
|
|
|
let Coordinate(ax, ay, az) = self;
|
|
|
|
|
|
let Coordinate(bx, by, bz) = *b;
|
|
|
|
|
|
|
|
|
let dx = (bx - ax).abs();
|
|
|
let dx = (bx - ax).abs();
|
|
|
let sx :i32 = if ax < bx { 1 } else { -1 };
|
|
|
let sx :i32 = if ax < bx { 1 } else { -1 };
|
|
|
let dy = -(by - ay).abs();
|
|
|
let dy = -(by - ay).abs();
|
|
|
let sy :i32 = if ay < by { 1 } else { -1 };
|
|
|
let sy :i32 = if ay < by { 1 } else { -1 };
|
|
|
|
|
|
let size = cmp::max(dx, -dy);
|
|
|
|
|
|
let dz = (bz - az) / size.into();
|
|
|
|
|
|
|
|
|
let mut v :Vec<Self> = vec!( Coordinate(0, 0)
|
|
|
|
|
|
; cmp::max(dx, -dy) as usize + 1);
|
|
|
|
|
|
v[0] = Coordinate(ax, ay);
|
|
|
|
|
|
inner(&mut v, bx, by, dx, dy, sx, sy, dx + dy);
|
|
|
|
|
|
|
|
|
let mut v :Vec<Self> = vec!( Coordinate(0, 0, 0.into())
|
|
|
|
|
|
; (size as usize) + 1);
|
|
|
|
|
|
v[0] = Coordinate(ax, ay, az);
|
|
|
|
|
|
inner(&mut v, bx, by, dx, dy, sx, sy, dz, dx + dy);
|
|
|
v
|
|
|
v
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl Display for Coordinate {
|
|
|
|
|
|
|
|
|
impl<T> Display for Coordinate<T> {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
write!(f, "<{},{}>", self.0, self.1)
|
|
|
write!(f, "<{},{}>", self.0, self.1)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl Display for Coordinates {
|
|
|
|
|
|
|
|
|
impl<T> Display for Coordinates<T> where T: Copy {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
let Coordinates(is) = self;
|
|
|
let Coordinates(is) = self;
|
|
|
|
|
|
|
|
|
@ -116,16 +123,16 @@ impl Display for Coordinates { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
pub struct Point(pub Coordinate);
|
|
|
|
|
|
|
|
|
pub struct Point<T>(pub Coordinate<T>);
|
|
|
|
|
|
|
|
|
impl Drawable for Point{
|
|
|
|
|
|
fn plot(&self) -> Coordinates {
|
|
|
|
|
|
|
|
|
impl<T> Drawable<T> for Point<T> where T: Copy {
|
|
|
|
|
|
fn plot(&self) -> Coordinates<T> {
|
|
|
let Point(c) = *self;
|
|
|
let Point(c) = *self;
|
|
|
Coordinates(vec!(c))
|
|
|
Coordinates(vec!(c))
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl Display for Point {
|
|
|
|
|
|
|
|
|
impl<T> Display for Point<T> {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
let Point(p) = self;
|
|
|
let Point(p) = self;
|
|
|
write!(f, "Point[{}]", p)
|
|
|
write!(f, "Point[{}]", p)
|
|
|
@ -133,30 +140,36 @@ impl Display for Point { |
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
pub struct Line(pub Coordinate, pub Coordinate);
|
|
|
|
|
|
|
|
|
pub struct Line<T>(pub Coordinate<T>, pub Coordinate<T>);
|
|
|
|
|
|
|
|
|
impl Drawable for Line {
|
|
|
|
|
|
fn plot(&self) -> Coordinates {
|
|
|
|
|
|
|
|
|
impl<T> Drawable<T> for Line<T>
|
|
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
|
|
|
|
|
|
+ Clone + Copy + From<i32> {
|
|
|
|
|
|
fn plot(&self) -> Coordinates<T> {
|
|
|
let Line(a, b) = *self;
|
|
|
let Line(a, b) = *self;
|
|
|
Coordinates(a.line(&b))
|
|
|
Coordinates(a.line(&b))
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl Display for Line {
|
|
|
|
|
|
|
|
|
impl<T> Display for Line<T> {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
let Line(a, b) = self;
|
|
|
let Line(a, b) = self;
|
|
|
write!(f, "Line[{},{}]", a, b)
|
|
|
write!(f, "Line[{},{}]", a, b)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// In 3D a rectangle is not as trivial as in 2D, it might be somehow rotate
|
|
|
|
|
|
// and thus we need to specify a Z offset for the other two corners.
|
|
|
|
|
|
// As I do not need rectangle at all I just comment out this code for now.
|
|
|
|
|
|
/*
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
pub struct Rectangle(pub Coordinate, pub Coordinate);
|
|
|
|
|
|
|
|
|
pub struct Rectangle<T>(pub Coordinate<T>, pub Coordinate<T>);
|
|
|
|
|
|
|
|
|
impl Drawable for Rectangle {
|
|
|
|
|
|
fn plot(&self) -> Coordinates {
|
|
|
|
|
|
|
|
|
impl<T> Drawable<T> for Rectangle<T> {
|
|
|
|
|
|
fn plot(&self) -> Coordinates<T> {
|
|
|
let Rectangle(a, c) = *self;
|
|
|
let Rectangle(a, c) = *self;
|
|
|
let Coordinate(ax, ay) = a;
|
|
|
|
|
|
let Coordinate(cx, cy) = c;
|
|
|
|
|
|
|
|
|
let Coordinate(ax, ay, az) = a;
|
|
|
|
|
|
let Coordinate(cx, cy, cz) = c;
|
|
|
let b = Coordinate(cx, ay);
|
|
|
let b = Coordinate(cx, ay);
|
|
|
let d = Coordinate(ax, cy);
|
|
|
let d = Coordinate(ax, cy);
|
|
|
|
|
|
|
|
|
@ -177,16 +190,19 @@ impl Display for Rectangle { |
|
|
write!(f, "Rec[{},{}]", a, b)
|
|
|
write!(f, "Rec[{},{}]", a, b)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
#[derive(Debug, Clone)]
|
|
|
pub struct Polyline(pub Coordinates);
|
|
|
|
|
|
|
|
|
pub struct Polyline<T>(pub Coordinates<T>);
|
|
|
|
|
|
|
|
|
impl Drawable for Polyline {
|
|
|
|
|
|
fn plot(&self) -> Coordinates {
|
|
|
|
|
|
|
|
|
impl<T> Drawable<T> for Polyline<T>
|
|
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
|
|
|
|
|
|
+ Clone + Copy + From<i32> {
|
|
|
|
|
|
fn plot(&self) -> Coordinates<T> {
|
|
|
let Polyline(Coordinates(cs)) = self;
|
|
|
let Polyline(Coordinates(cs)) = self;
|
|
|
|
|
|
|
|
|
match cs[..] {
|
|
|
match cs[..] {
|
|
|
[] => Coordinates(Vec::<Coordinate>::new()),
|
|
|
|
|
|
|
|
|
[] => Coordinates(Vec::<Coordinate<T>>::new()),
|
|
|
[a] => Coordinates(vec!(a)),
|
|
|
[a] => Coordinates(vec!(a)),
|
|
|
[a, b] => Coordinates(a.line(&b)),
|
|
|
[a, b] => Coordinates(a.line(&b)),
|
|
|
_ => {
|
|
|
_ => {
|
|
|
@ -203,7 +219,7 @@ impl Drawable for Polyline { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl Display for Polyline {
|
|
|
|
|
|
|
|
|
impl<T> Display for Polyline<T> where T: Copy {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
let Polyline(a) = self;
|
|
|
let Polyline(a) = self;
|
|
|
write!(f, "PLine[{}]", a)
|
|
|
write!(f, "PLine[{}]", a)
|
|
|
@ -211,14 +227,16 @@ impl Display for Polyline { |
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
#[derive(Debug, Clone)]
|
|
|
pub struct Polygon(pub Coordinates);
|
|
|
|
|
|
|
|
|
pub struct Polygon<T>(pub Coordinates<T>);
|
|
|
|
|
|
|
|
|
impl Drawable for Polygon {
|
|
|
|
|
|
fn plot(&self) -> Coordinates {
|
|
|
|
|
|
|
|
|
impl<T> Drawable<T> for Polygon<T>
|
|
|
|
|
|
where T: Add<Output = T> + Sub<Output = T> + Div<Output = T>
|
|
|
|
|
|
+ Clone + Copy + From<i32> {
|
|
|
|
|
|
fn plot(&self) -> Coordinates<T> {
|
|
|
let Polygon(Coordinates(cs)) = self;
|
|
|
let Polygon(Coordinates(cs)) = self;
|
|
|
|
|
|
|
|
|
match cs[..] {
|
|
|
match cs[..] {
|
|
|
[] => Coordinates(Vec::<Coordinate>::new()),
|
|
|
|
|
|
|
|
|
[] => Coordinates(Vec::<Coordinate<T>>::new()),
|
|
|
[a] => Coordinates(vec!(a)),
|
|
|
[a] => Coordinates(vec!(a)),
|
|
|
[a, b] => Coordinates(a.line(&b)),
|
|
|
[a, b] => Coordinates(a.line(&b)),
|
|
|
_ => {
|
|
|
_ => {
|
|
|
@ -240,7 +258,7 @@ impl Drawable for Polygon { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl Display for Polygon {
|
|
|
|
|
|
|
|
|
impl<T> Display for Polygon<T> where T: Copy {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
|
let Polygon(a) = self;
|
|
|
let Polygon(a) = self;
|
|
|
write!(f, "Poly[{}]", a)
|
|
|
write!(f, "Poly[{}]", a)
|
|
|
|