図形表現の定義

他の幾何ライブラリはこれに依存する

geo.2d.rs

#[derive(Debug, Clone, Copy)]
struct Point(f64, f64);

impl Point {
    fn norm(self) -> f64 {
        (self * self).sqrt()
    }
    fn det(self, other: Point) -> f64 {
        self.0 * other.1 - self.1 * other.0
    }
    fn arg(self) -> f64 {
        let x = self.0 / self.norm();
        (if x < -1.0 { -1.0 } else if x > 1.0 { 1.0 } else { x } as f64).acos()
    }
}

use std::cmp::{PartialEq, Eq};
impl PartialEq for Point {
    fn eq(&self, other: &Point) -> bool {
        let eps = 0.0001;
        (self.0 - other.0).abs() < eps && (self.1 - other.1).abs() < eps
    }
    fn ne(&self, other: &Point) -> bool {
        !(self == other)
    }
}
impl Eq for Point { }

use std::ops::{Add, Sub, Neg, Mul, Div};
impl Add for Point {
    type Output = Point;
    fn add(self, other: Point) -> Point {
        Point(self.0 + other.0, self.1 + other.1)
    }
}

impl Neg for Point {
    type Output = Point;
    fn neg(self) -> Point {
        Point(-self.0, -self.1)
    }
}

impl Sub for Point {
    type Output = Point;
    fn sub(self, other: Point) -> Point {
        self + (-other)
    }
}

// scalar multiplication
impl Mul<Point> for f64 {
    type Output = Point;
    fn mul(self, other: Point) -> Point {
        Point(self * other.0, self * other.1)
    }
}

impl Mul<f64> for Point {
    type Output = Point;
    fn mul(self, other: f64) -> Point {
        Point(other * self.0, other * self.1)
    }
}

// inner-product
impl Mul<Point> for Point {
    type Output = f64;
    fn mul(self, other: Point) -> f64 {
        self.0 * other.0 + self.1 * other.1
    }
}

impl Div<f64> for Point {
    type Output = Point;
    fn div(self, other: f64) -> Point {
        Point(self.0 / other, self.1 / other)
    }
}

#[derive(Debug, Clone, Copy)]
struct Line(Point, Point);

impl Line {
    fn len(self) -> f64 {
        (self.0 - self.1).norm()
    }
    fn rev(self) -> Line {
        Line(self.1, self.0)
    }
}

#[derive(Debug, Clone, Copy)]
struct Circle(Point, f64);

geo.2d.cc

using Real = long double;
const Real PI = acosl(-1);
using P = pair<Real, Real>; // Point
using L = pair<P, P>; // segment or line

/* inner dot */
Real dot(P&a, P&b) {
    return a.first * b.first + a.second * b.second;
}
Real operator*(P&a, P&b) {
    return a.first * b.first + a.second * b.second;
}

/* scalar multiple */
P operator*(P a, Real c) {
    return {c * a.first, c * a.second};
}
P operator*(Real c, P a) {
    return {c * a.first, c * a.second};
}

P operator/(P a, Real d) {
    return {a.first / d, a.second / d};
}

Real det(P a, P b) {
    return a.first * b.second - a.second * b.first;
}

/* vector operator */
P operator+(P a, P b) {
    return {a.first + b.first, a.second + b.second};
}

P operator-(P a) {
    return {-a.first, -a.second};
}

P operator-(P a, P b) {
    return {a.first - b.first, a.second - b.second};
}

/* distance */
Real Manhattan(P a, P b) {
    return abs(a.first - b.first) + abs(a.second - b.second);
}
Real Euclidean(P a, P b) {
    P p = a - b;
    return sqrt(p.first*p.first + p.second*p.second);
}

/* equality with eps (default: 1e-9) */
bool eq(Real x, Real y) {
    return abs(x - y) < eps;
}
bool operator==(P a, P b) {
    return eq(a.first, b.first) && eq(a.second, b.second);
}

int sign(Real a) {
    if (eq(a, 0)) return 0;
    return a > 0 ? 1 : -1;
}

Real magnitude(P p) {
    return sqrt(p.first*p.first + p.second*p.second);
}

Real arg(P a, P b) {
    Real x = dot(a, b) / magnitude(a) / magnitude(b);
    x = min<Real>(1, max<Real>(-1, x));
    return acos(x);
}