def extendPolylineOnto(self, polyline, k): if self.intersectsPolyline(polyline, k): return None if len(polyline) > 1: fault_polyline = self.getPolyline(k) ext1 = self.__rayIntersect(polyline[-2], polyline[-1], fault_polyline) ext2 = self.__rayIntersect(polyline[0], polyline[1], fault_polyline) if ext1 and ext2: d1 = GeometryTools.distance(ext1[0], ext1[1]) d2 = GeometryTools.distance(ext2[0], ext2[1]) if d1 < d2: return ext1 else: return ext2 if ext1: return ext1 else: return ext2 else: raise ValueError("Polyline must have length >= 2")
def extendToFault(self , other_fault , k): polyline = self.getIJPolyline(k) p0 = polyline[-2] p1 = polyline[-1] ray_dir = GeometryTools.lineToRay( p0 , p1 ) intersections = GeometryTools.rayPolygonIntersections( p1 , ray_dir , other_fault.getIJPolyline(k)) if intersections: p2 = intersections[0][1] return [p1 , (int(p2[0]) , int(p2[1])) ] p0 = polyline[1] p1 = polyline[0] ray_dir = GeometryTools.lineToRay( p0 , p1 ) intersections = GeometryTools.rayPolygonIntersections( p1 , ray_dir , other_fault.getIJPolyline(k)) if intersections: if len(intersections) > 1: d_list = [ GeometryTools.distance( p1 , p[1] ) for p in intersections ] index = d_list.index( min(d_list) ) else: index = 0 p2 = intersections[index][1] return [p1 , (int(p2[0]) , int(p2[1])) ] raise ValueError("The fault %s can not be extended to intersect with:%s in layer:%d" % (self.getName() , other_fault.getName() , k+1 ))
def test_ray_line_intersection(self): p = GeometryTools.rayLineIntersection((0,0) , (1,0) , (5,-1),(5,1)) self.assertEqual( p , (5,0)) self.assertIsNone( GeometryTools.rayLineIntersection((0,0) , (-1,0) , (5,-1),(5,1)) ) self.assertIsNone( GeometryTools.rayLineIntersection((0,0) , (0,1) , (5,-1),(5,1)) ) self.assertIsNone( GeometryTools.rayLineIntersection((0,0) , (0,-1) , (5,-1),(5,1)) ) p = GeometryTools.rayLineIntersection((0,0) , (1,1) , (5,-6),(5,6)) self.assertEqual( p , (5,5))
def containsPolyline(self, polyline): """ Will return true if at least one point from the polyline is inside the block. """ edge_polyline = self.getEdgePolygon() for p in polyline: if GeometryTools.pointInPolygon( p , edge_polyline ): return True else: edge_polyline.assertClosed() return GeometryTools.polylinesIntersect( edge_polyline , polyline )
def containsPolyline(self, polyline): """ Will return true if at least one point from the polyline is inside the block. """ edge_polyline = self.getEdgePolygon() for p in polyline: if GeometryTools.pointInPolygon(p, edge_polyline): return True else: edge_polyline.assertClosed() return GeometryTools.polylinesIntersect(edge_polyline, polyline)
def __rayIntersect(p0, p1 , polyline): ray_dir = GeometryTools.lineToRay( p0 , p1 ) intersections = GeometryTools.rayPolygonIntersections( p1 , ray_dir , polyline) if intersections: if len(intersections) > 1: d_list = [ GeometryTools.distance( p1 , p[1] ) for p in intersections ] index = d_list.index( min(d_list) ) else: index = 0 p2 = intersections[index][1] return [p1 , p2] else: return None
def test_intersection(self): p1 = Polyline(init_points=[(0, 0), (1, 0)]) p2 = Polyline(init_points=[(0.5, 0.5), (0.5, -0.5)]) p3 = Polyline(init_points=[(0, 1), (1, 1)]) self.assertTrue(GeometryTools.polylinesIntersect(p1, p2)) self.assertFalse(GeometryTools.polylinesIntersect(p2, p3)) self.assertFalse(GeometryTools.polylinesIntersect(p1, p3)) self.assertTrue(p1.intersects(p2)) self.assertTrue(p2.intersects(p1)) self.assertTrue(not p1.intersects(p3)) self.assertTrue(not p3.intersects(p1))
def test_intersection(self): p1 = Polyline( init_points = [(0,0) , (1,0)]) p2 = Polyline( init_points = [(0.5 , 0.5) , (0.5,-0.5)]) p3 = Polyline( init_points = [(0,1) , (1,1)]) self.assertTrue(GeometryTools.polylinesIntersect( p1 , p2 )) self.assertFalse( GeometryTools.polylinesIntersect( p2 , p3 )) self.assertFalse( GeometryTools.polylinesIntersect( p1 , p3 )) self.assertTrue( p1.intersects(p2) ) self.assertTrue( p2.intersects(p1) ) self.assertTrue( not p1.intersects(p3) ) self.assertTrue( not p3.intersects(p1) )
def test_intersection(self): p1 = (0.0, 0.0) p2 = (10.0, 0.0) p3 = (5.0, -5.0) p4 = (5.0, 5.0) self.assertEqual(GeometryTools.lineIntersection(p1, p2, p3, p4), (5.0, 0.0)) p5 = (0.0, 5.0) self.assertEqual(GeometryTools.lineIntersection(p1, p2, p3, p5), (2.5, 0)) self.assertEqual(GeometryTools.lineIntersection((0.0, 0.0), (1.0, 1.0), (0.0, 1.0), (1.0, 0.0)), (0.5, 0.5))
def test_ray_line_intersection(self): p = GeometryTools.rayLineIntersection((0, 0), (1, 0), (5, -1), (5, 1)) self.assertEqual(p, (5, 0)) self.assertIsNone( GeometryTools.rayLineIntersection((0, 0), (-1, 0), (5, -1), (5, 1))) self.assertIsNone( GeometryTools.rayLineIntersection((0, 0), (0, 1), (5, -1), (5, 1))) self.assertIsNone( GeometryTools.rayLineIntersection((0, 0), (0, -1), (5, -1), (5, 1))) p = GeometryTools.rayLineIntersection((0, 0), (1, 1), (5, -6), (5, 6)) self.assertEqual(p, (5, 5))
def splitFaultBlocks(self , grid , fault_blocks ): boundingPolygon = Polyline(init_points = grid.getBoundingBox2D()) boundingPolygon.assertClosed() if self.hasPolygon(): if len(self.edges) == 1: return self.splitFaultBlockClosedPolygon( grid , fault_blocks , self.edges[0] ) else: current_fault_block_layer = fault_blocks k = fault_blocks.getK() for edge in self.edges: if isinstance(edge , Polyline): # Start on a brand new fault block layer. next_fault_block_layer = FaultBlockLayer( grid , k ) for block in current_fault_block_layer: if block.containsPolyline(edge): print "Block %d is split due to edge:%s" % (block.getBlockID() , edge.name()) sliced = GeometryTools.slicePolygon( boundingPolygon , edge ) inside_list = [] outside_list = [] for p in block: if GeometryTools.pointInPolygon( (p.x , p.y) , sliced ): inside_list.append( p ) else: outside_list.append( p ) if len(inside_list) * len(outside_list) == 0: new_block = next_fault_block_layer.addBlock( ) for p in inside_list: new_block.addCell(p.i , p.j) for p in outside_list: new_block.addCell(p.i , p.j) else: layer = Layer( grid.getNX() , grid.getNY() ) for p in inside_list: layer[p.i , p.j] = 1 for p in outside_list: layer[p.i , p.j] = 2 next_fault_block_layer.scanLayer( layer ) else: next_fault_block_layer.insertBlockContent( block ) current_fault_block_layer = next_fault_block_layer return current_fault_block_layer else: return fault_blocks
def test_intersection_outside_segments(self): p1 = (0.0, 0.0) p2 = (10.0, 0.0) p3 = (-1.0, -1.0) p4 = (-1.0, 1.0) self.assertIsNone(GeometryTools.lineIntersection(p1, p2, p3, p4))
def test_parallel(self): p1 = (0.0, 0.0) p2 = (10.0, 0.0) p3 = (0.0, 1.0) p4 = (10.0, 1.0) self.assertIsNone(GeometryTools.lineIntersection(p1, p2, p3, p4))
def test_intersection(self): p1 = (0.0, 0.0) p2 = (10.0, 0.0) p3 = (5.0, -5.0) p4 = (5.0, 5.0) self.assertEqual(GeometryTools.lineIntersection(p1, p2, p3, p4), (5.0, 0.0)) p5 = (0.0, 5.0) self.assertEqual(GeometryTools.lineIntersection(p1, p2, p3, p5), (2.5, 0)) self.assertEqual( GeometryTools.lineIntersection((0.0, 0.0), (1.0, 1.0), (0.0, 1.0), (1.0, 0.0)), (0.5, 0.5))
def endJoin(self , other , k): fault_polyline = self.getPolyline(k) if isinstance(other , Fault): other_polyline = other.getPolyline(k) else: other_polyline = other return GeometryTools.joinPolylines( fault_polyline , other_polyline )
def containsPolyline(self, polyline): """ Will return true if at least one point from the polyline is inside the block. """ edge_polyline = self.getEdgePolygon() for p in polyline: if GeometryTools.pointInPolygon( p , edge_polyline ): return True return False
def countInside(self , polygon): """ Will count the number of points in block which are inside polygon. """ inside = 0 for p in self: if GeometryTools.pointInPolygon( (p.x , p.y) , polygon ): inside += 1 return inside
def test_extend_to_edge(self): bound = Polyline( init_points = [(0,0) , (1,0) , (1,1) , (0,1)] ) l1 = Polyline( init_points = [(-1,0.5) , (0.5, 0.5)]) l2 = Polyline( init_points = [(0.25,0.25) , (0.75, 0.75)]) # Bound is not closed with self.assertRaises(AssertionError): GeometryTools.extendToEdge( bound , l1 ) bound.assertClosed() # l1 is not fully contained in bound with self.assertRaises(ValueError): GeometryTools.extendToEdge( bound , l1 ) l3 = GeometryTools.extendToEdge( bound , l2 ) self.assertEqual( l3[0] , (0.00,0.00)) self.assertEqual( l3[1] , (0.25,0.25)) self.assertEqual( l3[2] , (0.75,0.75)) self.assertEqual( l3[3] , (1.00,1.00)) self.assertEqual( len(l3) , 4)
def test_extend_to_edge(self): bound = Polyline(init_points=[(0, 0), (1, 0), (1, 1), (0, 1)]) l1 = Polyline(init_points=[(-1, 0.5), (0.5, 0.5)]) l2 = Polyline(init_points=[(0.25, 0.25), (0.75, 0.75)]) # Bound is not closed with self.assertRaises(AssertionError): GeometryTools.extendToEdge(bound, l1) bound.assertClosed() # l1 is not fully contained in bound with self.assertRaises(ValueError): GeometryTools.extendToEdge(bound, l1) l3 = GeometryTools.extendToEdge(bound, l2) self.assertEqual(l3[0], (0.00, 0.00)) self.assertEqual(l3[1], (0.25, 0.25)) self.assertEqual(l3[2], (0.75, 0.75)) self.assertEqual(l3[3], (1.00, 1.00)) self.assertEqual(len(l3), 4)
def extendToBBox(self , bbox , k , start = True): fault_polyline = self.getPolyline(k) if start: p0 = fault_polyline[1] p1 = fault_polyline[0] else: p0 = fault_polyline[-2] p1 = fault_polyline[-1] ray_dir = GeometryTools.lineToRay(p0,p1) intersections = GeometryTools.rayPolygonIntersections( p1 , ray_dir , bbox) if intersections: p2 = intersections[0][1] if self.getName(): name = "Extend:%s" % self.getName() else: name = None return CPolyline( name = name , init_points = [(p1[0] , p1[1]) , p2]) else: raise Exception("Logical error - must intersect with bounding box")
def splitFaultBlockClosedPolygon( grid , fault_blocks , polygon ): """ Special case code when the region is limited only by one polygon. """ new_fault_blocks = FaultBlockLayer( grid , fault_blocks.getK() ) new_block = new_fault_blocks.addBlock() for block in fault_blocks: for p in block: if GeometryTools.pointInPolygon( (p.x , p.y) , polygon ): new_block.addCell(p.i , p.j) return new_fault_blocks
def extendPolylineOnto(self , polyline , k): if self.intersectsPolyline( polyline , k): return None if len(polyline) > 1: fault_polyline = self.getPolyline(k) ext1 = self.__rayIntersect( polyline[-2] , polyline[-1] , fault_polyline ) ext2 = self.__rayIntersect( polyline[0] , polyline[1] , fault_polyline ) if ext1 and ext2: d1 = GeometryTools.distance( ext1[0] , ext1[1] ) d2 = GeometryTools.distance( ext2[0] , ext2[1] ) if d1 < d2: return ext1 else: return ext2 if ext1: return ext1 else: return ext2 else: raise ValueError("Polyline must have length >= 2")
def __convexHull(self , k): point_list = [] if len(self.edges) == 0: raise Exception("You must add Fault / Polyline edges first") for edge in self.edges: if isinstance(edge , Fault): fault = edge layer = fault[k] for line in layer: for p in line.getPolyline(): point_list.append( (p[0] , p[1]) ) else: poly_line = edge for p in poly_line: point_list.append( (p[0] , p[1]) ) return GeometryTools.convexHull( point_list )
def test_distance(self): p1 = (1, 1) p2 = (1, 2, 3) with self.assertRaises(ValueError): GeometryTools.distance(p1, p2) with self.assertRaises(TypeError): GeometryTools.distance(1, p2) p2 = (2, 2) self.assertEqual(GeometryTools.distance(p1, p2), math.sqrt(2)) p1 = (1, 1, 1) p2 = (2, 2, 2) self.assertEqual(GeometryTools.distance(p1, p2), math.sqrt(3))
def test_distance(self): p1 = (1,1) p2 = (1,2,3) with self.assertRaises(ValueError): GeometryTools.distance( p1 , p2) with self.assertRaises(TypeError): GeometryTools.distance( 1 , p2 ) p2 = (2,2) self.assertEqual( GeometryTools.distance( p1 , p2) , math.sqrt(2)) p1 = (1,1,1) p2 = (2,2,2) self.assertEqual( GeometryTools.distance( p1 , p2) , math.sqrt(3))
def test_join__polylines(self): l1 = Polyline( init_points = [(0,1) , (1,1)]) l2 = CPolyline( init_points = [(2,-1) , (2,0)]) l3 = CPolyline( init_points = [(2,2) , (2,3)]) l4 = Polyline( ) l5 = CPolyline( init_points = [(0.5,0),(0.5,2)] ) with self.assertRaises( ValueError ): GeometryTools.joinPolylines( l1 , l4 ) with self.assertRaises( ValueError ): GeometryTools.joinPolylines( l4 , l1 ) self.assertIsNone( GeometryTools.joinPolylines( l1 , l5 )) self.assertEqual( GeometryTools.joinPolylines( l1 , l2 ) , [(1,1) , (2,0)] )
def test_join__polylines(self): l1 = Polyline(init_points=[(0, 1), (1, 1)]) l2 = CPolyline(init_points=[(2, -1), (2, 0)]) l3 = CPolyline(init_points=[(2, 2), (2, 3)]) l4 = Polyline() l5 = CPolyline(init_points=[(0.5, 0), (0.5, 2)]) with self.assertRaises(ValueError): GeometryTools.joinPolylines(l1, l4) with self.assertRaises(ValueError): GeometryTools.joinPolylines(l4, l1) self.assertIsNone(GeometryTools.joinPolylines(l1, l5)) self.assertEqual(GeometryTools.joinPolylines(l1, l2), [(1, 1), (2, 0)])
def test_join_extend_polylines_onto(self): l1 = Polyline( init_points = [(0,1) , (1,1)]) l2 = CPolyline( init_points = [(2,0) , (2,2)]) l3 = CPolyline( init_points = [(0.5 , 0) , (0.5 , 2)]) l4 = Polyline( init_points = [(0,5) , (1,5)]) l5 = Polyline( init_points = [(0,5)]) self.assertIsNone( GeometryTools.connectPolylines( l1 , l3 )) with self.assertRaises( ValueError ): GeometryTools.connectPolylines( l1 , l5 ) with self.assertRaises( ValueError ): GeometryTools.connectPolylines( l1 , l4 ) self.assertEqual( GeometryTools.connectPolylines( l1 , l2 ) , [(1,1) , (2,1)])
def test_join_extend_polylines_onto(self): l1 = Polyline(init_points=[(0, 1), (1, 1)]) l2 = CPolyline(init_points=[(2, 0), (2, 2)]) l3 = CPolyline(init_points=[(0.5, 0), (0.5, 2)]) l4 = Polyline(init_points=[(0, 5), (1, 5)]) l5 = Polyline(init_points=[(0, 5)]) self.assertIsNone(GeometryTools.connectPolylines(l1, l3)) with self.assertRaises(ValueError): GeometryTools.connectPolylines(l1, l5) with self.assertRaises(ValueError): GeometryTools.connectPolylines(l1, l4) self.assertEqual(GeometryTools.connectPolylines(l1, l2), [(1, 1), (2, 1)])
def test_coincident(self): p1 = (0.0, 0.0) p2 = (10.0, 10.0) self.assertEqual(GeometryTools.lineIntersection(p1, p2, p1, p2), (5.0, 5.0))
def test_coincident(self): p1 = (0.0, 0.0) p2 = (10.0, 10.0) self.assertIsNone(GeometryTools.lineIntersection(p1, p2, p1, p2))
def test_nearest_point(self): l1 = Polyline(init_points=[(0, 0), (10, 0)]) p = GeometryTools.nearestPointOnPolyline((5, 5), l1) self.assertEqual(p, (5, 0))
def test_nearest_point(self): l1 = Polyline( init_points = [(0,0) , (10,0)]) p = GeometryTools.nearestPointOnPolyline( (5 , 5) , l1 ) self.assertEqual( p , (5 , 0) )
def test_coincident(self): p1 = (0.0, 0.0) p2 = (10.0, 10.0) self.assertIsNone( GeometryTools.lineIntersection(p1, p2, p1, p2) )