/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/hittest.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/UI/hittest.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 2590 byte(s)
made a copy
1 # Copyright (C) 2003 by Intevation GmbH
2 # Authors:
3 # Martin Mueller <[email protected]>
4 # Bernhard Herzog <[email protected]>
5 #
6 # This program is free software under the GPL (>=v2)
7 # Read the file COPYING coming with the software for details.
8
9 """Hit testing functions"""
10
11 __version__ = "$Revision$"
12 # $Source$
13 # $Id$
14
15 from math import hypot, sqrt
16
17 def line_hit(sx, sy, ex, ey, px, py):
18 """Determine whether the line fom (SX, SY) to (EX, EY) is `hit' by a
19 click at (PX, PY), or whether a polygon containing this line is hit
20 in the interior at (PX, PY).
21
22 Return -1 if the line it self his hit. Otherwise, return +1 if a
23 horizontal line from (PX, PY) to (-Infinity, PY) intersects the line
24 and 0 if it doesn't.
25
26 The nonnegative return values can be used to determine whether (PX, PY)
27 is an interior point of a polygon according to the even-odd rule.
28 """
29
30 if (ey < sy):
31 sx, ex = ex, sx
32 sy, ey = ey, sy
33
34 not_horizontal = ey > sy + 2
35 if not_horizontal and (py >= ey or py < sy):
36 return 0
37
38 vx = ex - sx
39 vy = ey - sy
40
41 len = sqrt(vx * vx + vy * vy)
42 if not len:
43 # degenerate case of coincident end points. Assumes that some
44 # other part of the code has already determined whether the end
45 # point is hit.
46 return 0
47
48 dx = px - sx
49 dy = py - sy
50 dist = vx * dy - vy * dx
51
52 if ((not_horizontal or (px >= sx and px <= ex) or (px >= ex and px <= sx))
53 and abs(dist) <= (len * 2)):
54 return -1
55
56 # horizontal lines (vy == 0) always return 0 here.
57 return vy and py < ey and py >= sy and dx * abs(vy) > vx * abs(dy)
58
59
60 def polygon_hit(points, x, y):
61 """Return whether x, y is in the polygon or on or near the boundary
62
63 The return value is -1 if the point (x, y) is near the boundary, 1
64 if the point is inside and 0 if it's outside.
65
66 The points argument should be a list of lists of coordinate pairs.
67 """
68 crossings = 0
69 for ring in points:
70 for i in range(len(ring) - 1):
71 sx, sy = ring[i]
72 ex, ey = ring[i + 1]
73 hit = line_hit(sx, sy, ex, ey, x, y)
74 if hit < 0:
75 return hit
76 crossings += hit
77 return crossings % 2
78
79
80 def arc_hit(points, x, y):
81 """Return whether x, y is on or near the arc's boundary
82
83 The return value is -1 if the point (x, y) is near the boundary, 1
84 if the point is inside and 0 if it's outside.
85
86 The points argument should be a list of lists of coordinate pairs.
87 """
88 return polygon_hit(points, x, y) < 0

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26