distance_target.go (6776B)
1 // Copyright 2019 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package s2 16 17 import ( 18 "github.com/golang/geo/s1" 19 ) 20 21 // The distance interface represents a set of common methods used by algorithms 22 // that compute distances between various S2 types. 23 type distance interface { 24 // chordAngle returns this type as a ChordAngle. 25 chordAngle() s1.ChordAngle 26 27 // fromChordAngle is used to type convert a ChordAngle to this type. 28 // This is to work around needing to be clever in parts of the code 29 // where a distanceTarget interface method expects distances, but the 30 // user only supplies a ChordAngle, and we need to dynamically cast it 31 // to an appropriate distance interface types. 32 fromChordAngle(o s1.ChordAngle) distance 33 34 // zero returns a zero distance. 35 zero() distance 36 // negative returns a value smaller than any valid value. 37 negative() distance 38 // infinity returns a value larger than any valid value. 39 infinity() distance 40 41 // less is similar to the Less method in Sort. To get minimum values, 42 // this would be a less than type operation. For maximum, this would 43 // be a greater than type operation. 44 less(other distance) bool 45 46 // sub subtracts the other value from this one and returns the new value. 47 // This is done as a method and not simple mathematical operation to 48 // allow closest and furthest to implement this in opposite ways. 49 sub(other distance) distance 50 51 // chordAngleBound reports the upper bound on a ChordAngle corresponding 52 // to this distance. For example, if distance measures WGS84 ellipsoid 53 // distance then the corresponding angle needs to be 0.56% larger. 54 chordAngleBound() s1.ChordAngle 55 56 // updateDistance may update the value this distance represents 57 // based on the given input. The updated value and a boolean reporting 58 // if the value was changed are returned. 59 updateDistance(other distance) (distance, bool) 60 } 61 62 // distanceTarget is an interface that represents a geometric type to which distances 63 // are measured. 64 // 65 // For example, there are implementations that measure distances to a Point, 66 // an Edge, a Cell, a CellUnion, and even to an arbitrary collection of geometry 67 // stored in ShapeIndex. 68 // 69 // The distanceTarget types are provided for the benefit of types that measure 70 // distances and/or find nearby geometry, such as ClosestEdgeQuery, FurthestEdgeQuery, 71 // ClosestPointQuery, and ClosestCellQuery, etc. 72 type distanceTarget interface { 73 // capBound returns a Cap that bounds the set of points whose distance to the 74 // target is distance.zero(). 75 capBound() Cap 76 77 // updateDistanceToPoint updates the distance if the distance to 78 // the point P is within than the given dist. 79 // The boolean reports if the value was updated. 80 updateDistanceToPoint(p Point, dist distance) (distance, bool) 81 82 // updateDistanceToEdge updates the distance if the distance to 83 // the edge E is within than the given dist. 84 // The boolean reports if the value was updated. 85 updateDistanceToEdge(e Edge, dist distance) (distance, bool) 86 87 // updateDistanceToCell updates the distance if the distance to the cell C 88 // (including its interior) is within than the given dist. 89 // The boolean reports if the value was updated. 90 updateDistanceToCell(c Cell, dist distance) (distance, bool) 91 92 // setMaxError potentially updates the value of MaxError, and reports if 93 // the specific type supports altering it. Whenever one of the 94 // updateDistanceTo... methods above returns true, the returned distance 95 // is allowed to be up to maxError larger than the true minimum distance. 96 // In other words, it gives this target object permission to terminate its 97 // distance calculation as soon as it has determined that (1) the minimum 98 // distance is less than minDist and (2) the best possible further 99 // improvement is less than maxError. 100 // 101 // If the target takes advantage of maxError to optimize its distance 102 // calculation, this method must return true. (Most target types will 103 // default to return false.) 104 setMaxError(maxErr s1.ChordAngle) bool 105 106 // maxBruteForceIndexSize reports the maximum number of indexed objects for 107 // which it is faster to compute the distance by brute force (e.g., by testing 108 // every edge) rather than by using an index. 109 // 110 // The following method is provided as a convenience for types that compute 111 // distances to a collection of indexed geometry, such as ClosestEdgeQuery 112 // and ClosestPointQuery. 113 // 114 // Types that do not support this should return a -1. 115 maxBruteForceIndexSize() int 116 117 // distance returns an instance of the underlying distance type this 118 // target uses. This is to work around the use of Templates in the C++. 119 distance() distance 120 121 // visitContainingShapes finds all polygons in the given index that 122 // completely contain a connected component of the target geometry. (For 123 // example, if the target consists of 10 points, this method finds 124 // polygons that contain any of those 10 points.) For each such polygon, 125 // the visit function is called with the Shape of the polygon along with 126 // a point of the target geometry that is contained by that polygon. 127 // 128 // Optionally, any polygon that intersects the target geometry may also be 129 // returned. In other words, this method returns all polygons that 130 // contain any connected component of the target, along with an arbitrary 131 // subset of the polygons that intersect the target. 132 // 133 // For example, suppose that the index contains two abutting polygons 134 // A and B. If the target consists of two points "a" contained by A and 135 // "b" contained by B, then both A and B are returned. But if the target 136 // consists of the edge "ab", then any subset of {A, B} could be returned 137 // (because both polygons intersect the target but neither one contains 138 // the edge "ab"). 139 // 140 // If the visit function returns false, this method terminates early and 141 // returns false as well. Otherwise returns true. 142 // 143 // NOTE(roberts): This method exists only for the purpose of implementing 144 // edgeQuery IncludeInteriors efficiently. 145 visitContainingShapes(index *ShapeIndex, v shapePointVisitorFunc) bool 146 } 147 148 // shapePointVisitorFunc defines a type of function the visitContainingShapes can call. 149 type shapePointVisitorFunc func(containingShape Shape, targetPoint Point) bool