Package horizons :: Package util :: Package shapes :: Module distances
[hide private]
[frames] | no frames]

Source Code for Module horizons.util.shapes.distances

  1  # ################################################### 
  2  # Copyright (C) 2008-2017 The Unknown Horizons Team 
  3  # team@unknown-horizons.org 
  4  # This file is part of Unknown Horizons. 
  5  # 
  6  # Unknown Horizons is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the 
 18  # Free Software Foundation, Inc., 
 19  # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 20  # ################################################### 
 21   
 22   
 23  # Point 
24 -def distance_point_point(p1, p2):
25 return ((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2) ** 0.5
26 27
28 -def distance_point_tuple(point, coord_tuple):
29 x, y = coord_tuple 30 return ((point.x - x) ** 2 + (point.y - y) ** 2) ** 0.5
31 32
33 -def distance_point_circle(point, circle):
34 dist = point.distance(circle.center) - circle.radius 35 return dist if dist >= 0 else 0
36 37
38 -def distance_point_rect(point, rect):
39 return ((max(rect.left - point.x, 0, point.x - rect.right) ** 2) + 40 (max(rect.top - point.y, 0, point.y - rect.bottom) ** 2)) ** 0.5
41 42
43 -def distance_point_annulus(point, annulus):
44 dist = point.distance(annulus.center) 45 if dist < annulus.min_radius: 46 return annulus.min_radius - dist 47 if dist > annulus.max_radius: 48 return dist - annulus.max_radius 49 return 0
50 51 52 # Circle
53 -def distance_circle_circle(c1, c2):
54 dist = c1.distance(c2.center) - c1.radius - c2.radius 55 return dist if dist >= 0 else 0
56 57
58 -def distance_circle_tuple(circle, coord_tuple):
59 x, y = coord_tuple 60 dist = ((circle.center.x - x) ** 2 + (circle.center.y - y) ** 2) ** 0.5 - circle.radius 61 return dist if dist >= 0 else 0
62 63
64 -def distance_circle_annulus(circle, annulus):
65 dist = circle.distance(annulus.center) - circle.radius - annulus.max_radius 66 return dist if dist >= 0 else 0
67 68 69 # Rect
70 -def distance_rect_rect(r1, r2):
71 dx = 0 72 t = r1.left - r2.right 73 if t > dx: 74 dx = t 75 t = r2.left - r1.right 76 if t > dx: 77 dx = t 78 79 dy = 0 80 t = r1.top - r2.bottom 81 if t > dy: 82 dy = t 83 t = r2.top - r1.bottom 84 if t > dy: 85 dy = t 86 return (dx * dx + dy * dy) ** 0.5
87 88
89 -def distance_rect_rect_sq(r1, r2):
90 dx = 0 91 t = r1.left - r2.right 92 if t > dx: 93 dx = t 94 t = r2.left - r1.right 95 if t > dx: 96 dx = t 97 98 dy = 0 99 t = r1.top - r2.bottom 100 if t > dy: 101 dy = t 102 t = r2.top - r1.bottom 103 if t > dy: 104 dy = t 105 return dx * dx + dy * dy
106 107
108 -def distance_rect_tuple(rect, coord_tuple):
109 x, y = coord_tuple 110 dx = 0 111 t = rect.left - x 112 if t > dx: 113 dx = t 114 t = x - rect.right 115 if t > dx: 116 dx = t 117 118 dy = 0 119 t = rect.top - y 120 if t > dy: 121 dy = t 122 t = y - rect.bottom 123 if t > dy: 124 dy = t 125 return (dx * dx + dy * dy) ** 0.5
126 127
128 -def distance_rect_circle(rect, circle):
129 dist = rect.distance(circle.center) - circle.radius 130 return dist if dist >= 0 else 0
131 132
133 -def distance_rect_annulus(rect, annulus):
134 dist = rect.distance(annulus.center) - annulus.max_radius 135 return dist if dist >= 0 else 0
136 137 138 # Annulus
139 -def distance_annulus_annulus(a1, a2):
140 dist = a1.distance(a2.center) - a1.max_radius - a2.max_radius 141 return dist if dist >= 0 else 0
142 143
144 -def distance_annulus_tuple(annulus, coord_tuple):
145 (x, y) = coord_tuple 146 dist = ((annulus.center.x - x) ** 2 + (annulus.center.y - y) ** 2) ** 0.5 147 if dist < annulus.min_radius: 148 return annulus.min_radius - dist 149 if dist > annulus.max_radius: 150 return dist - annulus.max_radius 151 return 0
152 153 154 # DEBUG 155 if __name__ == '__main__': 156 import itertools 157 from . import distances 158 shapes = ('rect', 'point', 'tuple', 'circle', 'annulus') 159 for s1, s2 in itertools.product(shapes, shapes): 160 if not (hasattr(distances, 'distance_{}_{}'.format(s1, s2)) or 161 hasattr(distances, 'distance_{}_{}'.format(s2, s1))): 162 print('missing distance between', s1, s2) 163