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