Skip to content

Instantly share code, notes, and snippets.

@redrabbit
Created June 29, 2017 22:47
Show Gist options
  • Save redrabbit/5dca742e8147fd3af35dbcb763cef001 to your computer and use it in GitHub Desktop.
Save redrabbit/5dca742e8147fd3af35dbcb763cef001 to your computer and use it in GitHub Desktop.
Rust implementation of a Geometry trait (area, perimeter)
use std::fmt;
trait Geometry: fmt::Display {
fn perimeter(&self) -> f32;
fn area(&self) -> f32;
}
//
// Point
//
struct Point {
x: f32,
y: f32,
}
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
fn distance(a: &Point, b: &Point) -> f32 {
let dx = b.x - a.x;
let dy = b.y - a.y;
return (dx*dx + dy*dy).sqrt();
}
//
// Rectangle
//
struct Rectangle(Point, Point);
impl fmt::Display for Rectangle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Rectangle({}, {})", self.0, self.1)
}
}
impl Geometry for Rectangle {
fn perimeter(&self) -> f32 {
let w = self.0.x+self.1.x;
let h = self.0.y+self.1.y;
return w*2.0+h*2.0;
}
fn area(&self) -> f32 {
let w = self.0.x+self.1.x;
let h = self.0.y+self.1.y;
return w*h;
}
}
//
// Circle
//
struct Circle(Point, f32);
impl fmt::Display for Circle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Circle({}, {})", self.0, self.1)
}
}
impl Geometry for Circle {
fn perimeter(&self) -> f32 {
return std::f32::consts::PI * self.1 * 2.0;
}
fn area(&self) -> f32 {
return std::f32::consts::PI * self.1 * self.1;
}
}
//
// Triangle
//
struct Triangle(Point, Point, Point);
impl fmt::Display for Triangle {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Triangle({}, {}, {})", self.0, self.1, self.2)
}
}
impl Geometry for Triangle {
fn perimeter(&self) -> f32 {
let a = distance(&self.0, &self.1);
let b = distance(&self.0, &self.2);
let c = distance(&self.1, &self.2);
return a+b+c;
}
fn area(&self) -> f32 {
let a = distance(&self.0, &self.1);
let b = distance(&self.0, &self.2);
let c = distance(&self.1, &self.2);
let s = (a+b+c)/2.0;
return (s*(s-a)*(s-b)*(s-c)).sqrt();
}
}
fn main() {
let mut v: Vec<Box<Geometry>> = Vec::new();
v.push(Box::new(Rectangle(Point{x: 0.0, y: 0.0}, Point{x: 5.0, y: 5.0})));
v.push(Box::new(Circle(Point{x: 0.0, y: 0.0}, 5.0)));
v.push(Box::new(Triangle(Point{x: 0.0, y: 0.0}, Point{x: 5.0, y: 5.0}, Point{x: 0.0, y: 3.0})));
for f in v {
println!("{} --- perimeter = {} ; area = {}", f, f.perimeter(), f.area());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment