diff options
author | 2024-08-02 11:46:41 +0000 | |
---|---|---|
committer | 2024-08-02 12:46:41 +0100 | |
commit | 94e87610c4ce9bbb1c614a61bab29c1422fed11b (patch) | |
tree | 2e06b8ce64212140e796f6077ba841b6cc678501 /vendor/github.com/golang/geo/r2/rect.go | |
parent | [feature] Allow import of following and blocks via CSV (#3150) (diff) | |
download | gotosocial-94e87610c4ce9bbb1c614a61bab29c1422fed11b.tar.xz |
[chore] add back exif-terminator and use only for jpeg,png,webp (#3161)
* add back exif-terminator and use only for jpeg,png,webp
* fix arguments passed to terminateExif()
* pull in latest exif-terminator
* fix test
* update processed img
---------
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Diffstat (limited to 'vendor/github.com/golang/geo/r2/rect.go')
-rw-r--r-- | vendor/github.com/golang/geo/r2/rect.go | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/vendor/github.com/golang/geo/r2/rect.go b/vendor/github.com/golang/geo/r2/rect.go new file mode 100644 index 000000000..495545bba --- /dev/null +++ b/vendor/github.com/golang/geo/r2/rect.go @@ -0,0 +1,255 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package r2 + +import ( + "fmt" + "math" + + "github.com/golang/geo/r1" +) + +// Point represents a point in ℝ². +type Point struct { + X, Y float64 +} + +// Add returns the sum of p and op. +func (p Point) Add(op Point) Point { return Point{p.X + op.X, p.Y + op.Y} } + +// Sub returns the difference of p and op. +func (p Point) Sub(op Point) Point { return Point{p.X - op.X, p.Y - op.Y} } + +// Mul returns the scalar product of p and m. +func (p Point) Mul(m float64) Point { return Point{m * p.X, m * p.Y} } + +// Ortho returns a counterclockwise orthogonal point with the same norm. +func (p Point) Ortho() Point { return Point{-p.Y, p.X} } + +// Dot returns the dot product between p and op. +func (p Point) Dot(op Point) float64 { return p.X*op.X + p.Y*op.Y } + +// Cross returns the cross product of p and op. +func (p Point) Cross(op Point) float64 { return p.X*op.Y - p.Y*op.X } + +// Norm returns the vector's norm. +func (p Point) Norm() float64 { return math.Hypot(p.X, p.Y) } + +// Normalize returns a unit point in the same direction as p. +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) } + +// Rect represents a closed axis-aligned rectangle in the (x,y) plane. +type Rect struct { + X, Y r1.Interval +} + +// RectFromPoints constructs a rect that contains the given points. +func RectFromPoints(pts ...Point) Rect { + // Because the default value on interval is 0,0, we need to manually + // define the interval from the first point passed in as our starting + // interval, otherwise we end up with the case of passing in + // Point{0.2, 0.3} and getting the starting Rect of {0, 0.2}, {0, 0.3} + // instead of the Rect {0.2, 0.2}, {0.3, 0.3} which is not correct. + 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 +} + +// RectFromCenterSize constructs a rectangle with the given center and size. +// Both dimensions of size must be non-negative. +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}, + } +} + +// EmptyRect constructs the canonical empty rectangle. Use IsEmpty() to test +// for empty rectangles, since they have more than one representation. A Rect{} +// is not the same as the EmptyRect. +func EmptyRect() Rect { + return Rect{r1.EmptyInterval(), r1.EmptyInterval()} +} + +// IsValid reports whether the rectangle is valid. +// This requires the width to be empty iff the height is empty. +func (r Rect) IsValid() bool { + return r.X.IsEmpty() == r.Y.IsEmpty() +} + +// IsEmpty reports whether the rectangle is empty. +func (r Rect) IsEmpty() bool { + return r.X.IsEmpty() +} + +// Vertices returns all four vertices of the rectangle. Vertices are returned in +// CCW direction starting with the lower left corner. +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}, + } +} + +// VertexIJ returns the vertex in direction i along the X-axis (0=left, 1=right) and +// direction j along the Y-axis (0=down, 1=up). +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} +} + +// Lo returns the low corner of the rect. +func (r Rect) Lo() Point { + return Point{r.X.Lo, r.Y.Lo} +} + +// Hi returns the high corner of the rect. +func (r Rect) Hi() Point { + return Point{r.X.Hi, r.Y.Hi} +} + +// Center returns the center of the rectangle in (x,y)-space +func (r Rect) Center() Point { + return Point{r.X.Center(), r.Y.Center()} +} + +// Size returns the width and height of this rectangle in (x,y)-space. Empty +// rectangles have a negative width and height. +func (r Rect) Size() Point { + return Point{r.X.Length(), r.Y.Length()} +} + +// ContainsPoint reports whether the rectangle contains the given point. +// Rectangles are closed regions, i.e. they contain their boundary. +func (r Rect) ContainsPoint(p Point) bool { + return r.X.Contains(p.X) && r.Y.Contains(p.Y) +} + +// InteriorContainsPoint returns true iff the given point is contained in the interior +// of the region (i.e. the region excluding its boundary). +func (r Rect) InteriorContainsPoint(p Point) bool { + return r.X.InteriorContains(p.X) && r.Y.InteriorContains(p.Y) +} + +// Contains reports whether the rectangle contains the given rectangle. +func (r Rect) Contains(other Rect) bool { + return r.X.ContainsInterval(other.X) && r.Y.ContainsInterval(other.Y) +} + +// InteriorContains reports whether the interior of this rectangle contains all of the +// points of the given other rectangle (including its boundary). +func (r Rect) InteriorContains(other Rect) bool { + return r.X.InteriorContainsInterval(other.X) && r.Y.InteriorContainsInterval(other.Y) +} + +// Intersects reports whether this rectangle and the other rectangle have any points in common. +func (r Rect) Intersects(other Rect) bool { + return r.X.Intersects(other.X) && r.Y.Intersects(other.Y) +} + +// InteriorIntersects reports whether the interior of this rectangle intersects +// any point (including the boundary) of the given other rectangle. +func (r Rect) InteriorIntersects(other Rect) bool { + return r.X.InteriorIntersects(other.X) && r.Y.InteriorIntersects(other.Y) +} + +// AddPoint expands the rectangle to include the given point. The rectangle is +// expanded by the minimum amount possible. +func (r Rect) AddPoint(p Point) Rect { + return Rect{r.X.AddPoint(p.X), r.Y.AddPoint(p.Y)} +} + +// AddRect expands the rectangle to include the given rectangle. This is the +// same as replacing the rectangle by the union of the two rectangles, but +// is more efficient. +func (r Rect) AddRect(other Rect) Rect { + return Rect{r.X.Union(other.X), r.Y.Union(other.Y)} +} + +// ClampPoint returns the closest point in the rectangle to the given point. +// The rectangle must be non-empty. +func (r Rect) ClampPoint(p Point) Point { + return Point{r.X.ClampPoint(p.X), r.Y.ClampPoint(p.Y)} +} + +// Expanded returns a rectangle that has been expanded in the x-direction +// by margin.X, and in y-direction by margin.Y. If either margin is empty, +// then shrink the interval on the corresponding sides instead. The resulting +// rectangle may be empty. Any expansion of an empty rectangle remains empty. +func (r Rect) Expanded(margin Point) Rect { + xx := r.X.Expanded(margin.X) + yy := r.Y.Expanded(margin.Y) + if xx.IsEmpty() || yy.IsEmpty() { + return EmptyRect() + } + return Rect{xx, yy} +} + +// ExpandedByMargin returns a Rect that has been expanded by the amount on all sides. +func (r Rect) ExpandedByMargin(margin float64) Rect { + return r.Expanded(Point{margin, margin}) +} + +// Union returns the smallest rectangle containing the union of this rectangle and +// the given rectangle. +func (r Rect) Union(other Rect) Rect { + return Rect{r.X.Union(other.X), r.Y.Union(other.Y)} +} + +// Intersection returns the smallest rectangle containing the intersection of this +// rectangle and the given rectangle. +func (r Rect) Intersection(other Rect) Rect { + xx := r.X.Intersection(other.X) + yy := r.Y.Intersection(other.Y) + if xx.IsEmpty() || yy.IsEmpty() { + return EmptyRect() + } + + return Rect{xx, yy} +} + +// ApproxEqual returns true if the x- and y-intervals of the two rectangles are +// the same up to the given tolerance. +func (r Rect) ApproxEqual(r2 Rect) bool { + return r.X.ApproxEqual(r2.X) && r.Y.ApproxEqual(r2.Y) +} + +func (r Rect) String() string { return fmt.Sprintf("[Lo%s, Hi%s]", r.Lo(), r.Hi()) } |