func (r Rect) InteriorContains(other Rect) bool {
	return r.X.InteriorContainsInterval(other.X) && r.Y.InteriorContainsInterval(other.Y)
}
InteriorContains reports whether the interior of this rectangle contains all of the
points of the given other rectangle (including its boundary).
package r2
import (
	"fmt"
	"math"
	"github.com/golang/geo/r1"
)
type Point struct {
	X, Y float64
}
func (p Point) Add(op Point) Point { return Point{p.X + op.X, p.Y + op.Y} }
func (p Point) Sub(op Point) Point { return Point{p.X - op.X, p.Y - op.Y} }
func (p Point) Mul(m float64) Point { return Point{m * p.X, m * p.Y} }
func (p Point) Ortho() Point { return Point{-p.Y, p.X} }
func (p Point) Dot(op Point) float64 { return p.X*op.X + p.Y*op.Y }
func (p Point) Cross(op Point) float64 { return p.X*op.Y - p.Y*op.X }
func (p Point) Norm() float64 { return math.Hypot(p.X, p.Y) }
func (p Point) Normalize() Point {
	if p.X == 0 && p.Y == 0 {
		return p
	}
	return p.Mul(1 / p.Norm())
}
func (p Point) String() string { return fmt.Sprintf("(%.12f, %.12f)", p.X, p.Y) }
type Rect struct {
	X, Y r1.Interval
}
func RectFromPoints(pts ...Point) Rect {
	if len(pts) == 0 {
		return Rect{}
	}
	r := Rect{
		X: r1.Interval{Lo: pts[0].X, Hi: pts[0].X},
		Y: r1.Interval{Lo: pts[0].Y, Hi: pts[0].Y},
	}
	for _, p := range pts[1:] {
		r = r.AddPoint(p)
	}
	return r
}
func RectFromCenterSize(center, size Point) Rect {
	return Rect{
		r1.Interval{Lo: center.X - size.X/2, Hi: center.X + size.X/2},
		r1.Interval{Lo: center.Y - size.Y/2, Hi: center.Y + size.Y/2},
	}
}
func EmptyRect() Rect {
	return Rect{r1.EmptyInterval(), r1.EmptyInterval()}
}
func (r Rect) IsValid() bool {
	return r.X.IsEmpty() == r.Y.IsEmpty()
}
func (r Rect) IsEmpty() bool {
	return r.X.IsEmpty()
}
func (r Rect) Vertices() [4]Point {
	return [4]Point{
		{r.X.Lo, r.Y.Lo},
		{r.X.Hi, r.Y.Lo},
		{r.X.Hi, r.Y.Hi},
		{r.X.Lo, r.Y.Hi},
	}
}
func (r Rect) VertexIJ(i, j int) Point {
	x := r.X.Lo
	if i == 1 {
		x = r.X.Hi
	}
	y := r.Y.Lo
	if j == 1 {
		y = r.Y.Hi
	}
	return Point{x, y}
}
func (r Rect) Lo() Point {
	return Point{r.X.Lo, r.Y.Lo}
}
func (r Rect) Hi() Point {
	return Point{r.X.Hi, r.Y.Hi}
}
func (r Rect) Center() Point {
	return Point{r.X.Center(), r.Y.Center()}
}
func (r Rect) Size() Point {
	return Point{r.X.Length(), r.Y.Length()}
}
func (r Rect) ContainsPoint(p Point) bool {
	return r.X.Contains(p.X) && r.Y.Contains(p.Y)
}
func (r Rect) InteriorContainsPoint(p Point) bool {
	return r.X.InteriorContains(p.X) && r.Y.InteriorContains(p.Y)
}
func (r Rect) Contains(other Rect) bool {
	return r.X.ContainsInterval(other.X) && r.Y.ContainsInterval(other.Y)
}