4 |
4 |
5 def sign_consistency(container): |
5 def sign_consistency(container): |
6 # Returns whether all elements in container have the same sign |
6 # Returns whether all elements in container have the same sign |
7 return min(container) * max(container) >= 0 |
7 return min(container) * max(container) >= 0 |
8 |
8 |
9 @problem_type('concave', severity = 'error', message = 'concave quadrilateral') |
9 @problem_type('concave', severity = 'hold', message = 'concave quadrilateral') |
10 def concave_test(model): |
10 def concave_test(model): |
11 ''' Checks that all quadrilaterals are convex. ''' |
11 ''' Checks that all quadrilaterals are convex. ''' |
12 for quadrilateral in model.quadrilaterals: |
12 for quadrilateral in model.quadrilaterals: |
13 # Rotate the polygon into the XY plane. Then z is facing |
13 # Rotate the polygon into the XY plane. Then z is facing |
14 # away from the quadrilateral. |
14 # away from the quadrilateral. |
21 ] |
21 ] |
22 if not sign_consistency(z_scores): |
22 if not sign_consistency(z_scores): |
23 yield report_problem('concave', bad_object = quadrilateral) |
23 yield report_problem('concave', bad_object = quadrilateral) |
24 |
24 |
25 @problem_type('skew-major', |
25 @problem_type('skew-major', |
26 severity = 'error', |
26 severity = 'hold', |
27 message = lambda skew_angle: |
27 message = lambda skew_angle: |
28 str.format('skew quadrilateral (plane angle {})', |
28 str.format('skew quadrilateral (plane angle {})', |
29 degree_rep(skew_angle), |
29 degree_rep(skew_angle), |
30 ), |
30 ), |
31 ) |
31 ) |
32 @problem_type('skew-minor', |
32 @problem_type('skew-minor', |
33 severity = 'notice', |
33 severity = 'warning', |
34 message = lambda skew_angle: |
34 message = lambda skew_angle: |
35 str.format('slightly skew quadrilateral (plane angle {})', |
35 str.format('slightly skew quadrilateral (plane angle {})', |
36 degree_rep(skew_angle), |
36 degree_rep(skew_angle), |
37 ), |
37 ), |
38 ) |
38 ) |
57 skew_angle = skew_angle, |
57 skew_angle = skew_angle, |
58 ) |
58 ) |
59 break |
59 break |
60 |
60 |
61 @problem_type('self-intersecting', |
61 @problem_type('self-intersecting', |
62 severity = 'error', |
62 severity = 'hold', |
63 message = 'self-intersecting quadrilateral', |
63 message = 'self-intersecting quadrilateral', |
64 ) |
64 ) |
65 def bowtie_test(model): |
65 def bowtie_test(model): |
66 for quadrilateral in model.quadrilaterals: |
66 for quadrilateral in model.quadrilaterals: |
67 geometry = transform_to_xy(quadrilateral.geometry) |
67 geometry = transform_to_xy(quadrilateral.geometry) |
75 'self-intersecting', |
75 'self-intersecting', |
76 bad_object = quadrilateral, |
76 bad_object = quadrilateral, |
77 ) |
77 ) |
78 break |
78 break |
79 |
79 |
80 @problem_type('collinear', severity = 'error', message = 'collinear polygon') |
80 @problem_type('collinear', severity = 'hold', message = 'collinear polygon') |
81 def collinear_test(model): |
81 def collinear_test(model): |
82 for element in model.body: |
82 for element in model.body: |
83 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
83 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
84 for a, b, c in pairs(element.geometry.vertices, count = 3): |
84 for a, b, c in pairs(element.geometry.vertices, count = 3): |
85 if cross_product(b - a, c - a).length() < 1e-5: |
85 if cross_product(b - a, c - a).length() < 1e-5: |
86 yield report_problem('collinear', bad_object = element) |
86 yield report_problem('collinear', bad_object = element) |
87 |
87 |
88 @problem_type('hairline-polygon', |
88 @problem_type('hairline-polygon', |
89 severity = 'notice', |
89 severity = 'warning', |
90 message = lambda smallest_angle: str.format( |
90 message = lambda smallest_angle: str.format( |
91 'hairline polygon (smallest angle {})', |
91 'hairline polygon (smallest angle {})', |
92 degree_rep(smallest_angle), |
92 degree_rep(smallest_angle), |
93 ), |
93 ), |
94 ) |
94 ) |