-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A few elliptical/circular projections (#9)
* Aitoff projection * Add an example for Go pkg documentation * Simple distortion calculation tests added * Add Hammer projection and tests * A couple fixes * A couple more fixes for now * Another readme update * Lagrange projection, fixing a few planar bounds that diverge
- Loading branch information
1 parent
549fbd8
commit 586f5c0
Showing
10 changed files
with
243 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package flatsphere | ||
|
||
import "testing" | ||
|
||
func Test_DistortionNull(t *testing.T) { | ||
proj := NewMercator() | ||
eqArea, eqAngular := DistortionAt(proj, 0, 0) | ||
|
||
if !withinTolerance(eqArea, 0.0, 0.000001) || !withinTolerance(eqAngular, 0.0, 0.000001) { | ||
t.Errorf("expected 0, 0 distortion at mercator equator, got %f, %f", eqArea, eqAngular) | ||
} | ||
|
||
eqArea = AreaDistortionAt(proj, 0, 0) | ||
if !withinTolerance(eqArea, 0.0, 0.000001) { | ||
t.Errorf("expected 0 area distortion at mercator equator, got %f", eqArea) | ||
} | ||
|
||
eqAngular = AngularDistortionAt(proj, 0, 0) | ||
if !withinTolerance(eqAngular, 0.0, 0.000001) { | ||
t.Errorf("expected 0 angular distortion at mercator equator, got %f", eqAngular) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package flatsphere | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
) | ||
|
||
// Example_Reproject demonstrates taking a position in one projected plane and converting it into the analogous position | ||
// in a different projection. | ||
func Example_reproject() { | ||
// determine the original projection of the data | ||
original := NewMercator() | ||
// decide on a new desired projection of the data | ||
target := NewCassini() | ||
|
||
// take a point within the PlanarBounds() of the original projection | ||
ox, oy := math.Pi, math.Pi | ||
// get a latitude and longitude on the sphere from the original projected point | ||
lat, lon := original.Inverse(ox, oy) | ||
// get a projected point in the desired projection | ||
cx, cy := target.Project(lat, lon) | ||
|
||
fmt.Printf("original x, y: %f, %f\n", ox, oy) | ||
fmt.Printf("target x, y: %f, %f\n", cx, cy) | ||
|
||
// Output: original x, y: 3.141593, 3.141593 | ||
// target x, y: 0.000000, 1.657170 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package flatsphere | ||
|
||
import ( | ||
"math" | ||
) | ||
|
||
// A compromise azimuthal projection stretched into an elliptical shape. | ||
// https://en.wikipedia.org/wiki/Aitoff_projection | ||
type Aitoff struct{} | ||
|
||
func NewAitoff() Aitoff { | ||
return Aitoff{} | ||
} | ||
|
||
func (ai Aitoff) Project(lat float64, lon float64) (float64, float64) { | ||
a := math.Acos(math.Cos(lat) * math.Cos(lon/2)) | ||
if a == 0 { | ||
return 0, 0 | ||
} | ||
x := 2 * math.Cos(lat) * math.Sin(lon/2) * a / math.Sin(a) | ||
y := math.Sin(lat) * a / math.Sin(a) | ||
return x, y | ||
} | ||
|
||
func (ai Aitoff) Inverse(x float64, y float64) (float64, float64) { | ||
interLat, interLon := NewPolar().Inverse(x/2, y) | ||
transLat, transLon := NewObliqueAspect(0, 0, 0).TransformToOblique(interLat, interLon) | ||
return transLat, transLon * 2 | ||
} | ||
|
||
func (a Aitoff) PlanarBounds() Bounds { | ||
return NewEllipseBounds(math.Pi, math.Pi/2) | ||
} | ||
|
||
// An elliptical equal-area projection. | ||
// https://en.wikipedia.org/wiki/Hammer_projection | ||
type Hammer struct{} | ||
|
||
func NewHammer() Hammer { | ||
return Hammer{} | ||
} | ||
|
||
func (h Hammer) Project(lat float64, lon float64) (float64, float64) { | ||
z := math.Sqrt(1 + math.Cos(lat)*math.Cos(lon/2)) | ||
x := 2 * math.Cos(lat) * math.Sin(lon/2) / z | ||
y := math.Sin(lat) / z | ||
return x, y | ||
} | ||
|
||
func (h Hammer) Inverse(x float64, y float64) (float64, float64) { | ||
z := math.Sqrt(1 - x*x/8 - y*y/2) | ||
shift := 0.0 | ||
if math.Hypot(x/2, y) > 1 { | ||
shift = 2 * math.Pi | ||
if math.Signbit(x) { | ||
shift = -shift | ||
} | ||
} | ||
preAsin := z * y * math.Sqrt2 | ||
if preAsin > 1 && preAsin < 1+1e-9 { | ||
preAsin = 1 | ||
} | ||
if preAsin < -1 && preAsin > -1-1e-9 { | ||
preAsin = -1 | ||
} | ||
lat := math.Asin(preAsin) | ||
lon := 2*math.Atan(math.Sqrt(0.5)*z*x/(2*z*z-1)) + shift | ||
return lat, lon | ||
} | ||
|
||
func (h Hammer) PlanarBounds() Bounds { | ||
return NewEllipseBounds(2, 1) | ||
} | ||
|
||
// A circular conformal projection of the whole earth. | ||
type Lagrange struct{} | ||
|
||
func NewLagrange() Lagrange { | ||
return Lagrange{} | ||
} | ||
|
||
func (l Lagrange) Project(lat float64, lon float64) (float64, float64) { | ||
p := (1 + math.Sin(lat)) / (1 - math.Sin(lat)) | ||
v := math.Pow(p, 0.25) | ||
c := (v+1/v)/2 + math.Cos(lon/2) | ||
if math.IsInf(c, 0) { | ||
if math.Signbit(lat) { | ||
return 0, -1 | ||
} else { | ||
return 0, 1 | ||
} | ||
} | ||
x := math.Sin(lon/2) / c | ||
y := (v - 1/v) / (2 * c) | ||
return x, y | ||
} | ||
|
||
func (l Lagrange) Inverse(x float64, y float64) (float64, float64) { | ||
r2 := x*x + y*y | ||
th := 2 * y / (1 + r2) | ||
if th == 1 { | ||
if math.Signbit(y) { | ||
return -math.Pi / 2, 0 | ||
} else { | ||
return math.Pi / 2, 0 | ||
} | ||
} | ||
t := math.Pow((1+th)/(1-th), 2) | ||
lat := math.Asin((t - 1) / (t + 1)) | ||
lon := 2 * math.Atan2(2*x, 1-r2) | ||
return lat, lon | ||
} | ||
|
||
func (l Lagrange) PlanarBounds() Bounds { | ||
return NewCircleBounds(1) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters