tests/quadrilaterals.py

changeset 28
5933250813a3
parent 27
3089611c99d1
child 30
0d9ca37901ed
equal deleted inserted replaced
27:3089611c99d1 28:5933250813a3
7 return min(container) * max(container) >= 0 7 return min(container) * max(container) >= 0
8 8
9 def concave_test(model): 9 def concave_test(model):
10 ''' Checks that all quadrilaterals are convex. ''' 10 ''' Checks that all quadrilaterals are convex. '''
11 for quadrilateral in model.quadrilaterals: 11 for quadrilateral in model.quadrilaterals:
12 # Rotate the polygon into the XY plane. Then z is facing
13 # away from the quadrilateral.
12 geometry = transform_to_xy(quadrilateral.geometry) 14 geometry = transform_to_xy(quadrilateral.geometry)
15 # Now do a 2D concavity test:
16 # https://math.stackexchange.com/a/1745427
13 z_scores = [ 17 z_scores = [
14 cross_product(v2 - v1, v3 - v1).z 18 cross_product(v2 - v1, v3 - v1).z
15 for v1, v2, v3 in pairs(geometry.vertices, count = 3) 19 for v1, v2, v3 in pairs(geometry.vertices, count = 3)
16 ] 20 ]
17 if not sign_consistency(z_scores): 21 if not sign_consistency(z_scores):
33 yield warning(quadrilateral, 'skew-warning', 37 yield warning(quadrilateral, 'skew-warning',
34 skew_angle = skew_angle, 38 skew_angle = skew_angle,
35 ) 39 )
36 break 40 break
37 41
42 def bowtie_test(model):
43 for quadrilateral in model.quadrilaterals:
44 geometry = transform_to_xy(quadrilateral.geometry)
45 vertices = IndexRing(geometry.vertices)
46 for i in (0, 1):
47 line_1 = LineSegment(vertices[0 + i], vertices[1 + i])
48 line_2 = LineSegment(vertices[2 + i], vertices[3 + i])
49 intersection = line_segment_intersection_xy(line_1, line_2)
50 if intersection:
51 yield error(quadrilateral, 'self-intersecting')
52 break
53
38 manifest = { 54 manifest = {
39 'tests': { 55 'tests': {
40 'skew': skew_test, 56 'skew': skew_test,
41 'concave': concave_test, 57 'concave': concave_test,
58 'bowtie': bowtie_test,
42 }, 59 },
43 'messages': { 60 'messages': {
44 'skew-error': lambda skew_angle: 61 'skew-error': lambda skew_angle:
45 str.format('skew quadrilateral (plane angle {})', 62 str.format('skew quadrilateral (plane angle {})',
46 degree_rep(skew_angle), 63 degree_rep(skew_angle),
48 'skew-warning': lambda skew_angle: 65 'skew-warning': lambda skew_angle:
49 str.format('slightly skew quadrilateral (plane angle {})', 66 str.format('slightly skew quadrilateral (plane angle {})',
50 degree_rep(skew_angle), 67 degree_rep(skew_angle),
51 ), 68 ),
52 'concave-error': 'concave quadrilateral', 69 'concave-error': 'concave quadrilateral',
70 'self-intersecting': 'bowtie quadrilateral',
53 }, 71 },
54 } 72 }

mercurial