Thesis need to use a point
Self-reference
origin
Recently dizzy, suddenly want to study how the next judge after a coordinate point is within a polygon, this issue is resolved we can calculate the administrative division according to this point where the coordinates of a point.
algorithm
From the Internet to find a bit and found a very clever algorithm, the algorithm is as follows:
- The entire surface is divided into two portions (x> 0 && y == 0 || y> 0 section and x <0 && y == 0 || y <0 portion)
- Sequential scanning polygons each vertex when a vertex and the preceding vertex in the different parts, determine what the previous point to the origin point with respect to the direction of clockwise or counterclockwise (as determined by the cross-product), if it is clockwise r ++, or r - (r initially 0)
- If the result of r == 2 || r == - 2, the interior of the polygon is at the origin, otherwise not.
python achieve
def is_point_in(x, y, points): count = 0 x1, y1 = points[0] x1_part = (y1 > y) or ((x1 - x > 0) and (y1 == y)) # x1在哪一部分中 x2, y2 = '', '' # points[1] points.append((x1, y1)) for point in points[1:]: x2, y2 = point x2_part = (y2 > y) or ((x2 > x) and (y2 == y)) # x2在哪一部分中 if x2_part == x1_part: x1, y1 = x2, y2 continue mul = (x1 - x)*(y2 - y) - (x2 - x)*(y1 - y) if mul > 0: # 叉积大于0 逆时针 count += 1 elif mul < 0: count -= 1 x1, y1 = x2, y2 x1_part = x2_part if count == 2 or count == -2: return True else: return False if __name__ == '__main__': points = [[117.1510864068032,40.0705150448258],[117.2866776871509,40.10934259697606], ... ] y = 39.99 x = 116.468006 for i in xrange(10000): is_point_in(x + i * 0.01, y + i * 0.01, points)
operation hours
time python point.py
real 0m8.746s
user 0m8.680s
sys 0m0.034s
Performed 10,000 times, takes 8.746 seconds, too slow a wood there, try to go into
package main import ( //"fmt" ) func is_point_in(x float64, y float64, points [][]float64) bool { count := 0 x1, y1 := points[0][0], points[0][1] x1_part := (y1 > y) || ((x1 - x > 0) && (y1 == y)) var a = []float64{x1, y1} p := append(points, a) for i := range p { if (i == 0) { continue } point := p[i] x2, y2 := point[0], point[1] x2_part := (y2 > y) || ((x2 > x) && (y2 == y)) if (x2_part == x1_part){ x1, y1 = x2, y2 continue } mul := (x1 - x)*(y2 - y) - (x2 - x)*(y1 - y) if mul > 0 { count += 1 } else { if( mul < 0) { count -= 1 } } x1, y1 = x2, y2 x1_part = x2_part } if (count == 2 || count == -2){ return true } else { return false } } func main() { points := [][]float64{{117.1510864068032,40.0705150448258},{117.2866776871509,40.10934259697606}, ... ,} y := 39.99 x := 116.468006 for i:=1; i < 10000; i++ { _ = is_point_in(x + float64(i)*0.01, y + float64(i) * 0.01, points) } }
execution time:
go build point.go time ./point real 0m0.038s user 0m0.035s sys 0m0.005s