1 from math import radians |
1 from math import radians |
2 from testsuite import warning, error |
2 from testsuite import warning, error, notice |
3 from geometry import * |
3 from geometry import * |
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 |
56 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
56 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
57 for a, b, c in pairs(element.geometry.vertices, count = 3): |
57 for a, b, c in pairs(element.geometry.vertices, count = 3): |
58 if cross_product(b - a, c - a).length() < 1e-5: |
58 if cross_product(b - a, c - a).length() < 1e-5: |
59 yield error(element, 'collinearity-error') |
59 yield error(element, 'collinearity-error') |
60 |
60 |
|
61 def hairline_score(smallest_angle): |
|
62 from math import log10 |
|
63 return max(0, -log10(smallest_angle)) |
|
64 |
|
65 def hairline_test(model): |
|
66 for element in model.body: |
|
67 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
|
68 smallest_angle = element.geometry.smallest_angle |
|
69 if smallest_angle < radians(0.5): |
|
70 yield notice(element, 'hairline-warning', |
|
71 smallest_angle = smallest_angle, |
|
72 ) |
|
73 |
61 manifest = { |
74 manifest = { |
62 'tests': { |
75 'tests': { |
63 'skew': skew_test, |
76 'skew': skew_test, |
64 'concave': concave_test, |
77 'concave': concave_test, |
65 'bowtie': bowtie_test, |
78 'bowtie': bowtie_test, |
66 'collinearity': collinear_test, |
79 'collinearity': collinear_test, |
|
80 'hairline': hairline_test, |
67 }, |
81 }, |
68 'messages': { |
82 'messages': { |
69 'skew-error': lambda skew_angle: |
83 'skew-error': lambda skew_angle: |
70 str.format('skew quadrilateral (plane angle {})', |
84 str.format('skew quadrilateral (plane angle {})', |
71 degree_rep(skew_angle), |
85 degree_rep(skew_angle), |
75 degree_rep(skew_angle), |
89 degree_rep(skew_angle), |
76 ), |
90 ), |
77 'concave-error': 'concave quadrilateral', |
91 'concave-error': 'concave quadrilateral', |
78 'self-intersecting': 'bowtie quadrilateral', |
92 'self-intersecting': 'bowtie quadrilateral', |
79 'collinearity-error': 'collinear polygon', |
93 'collinearity-error': 'collinear polygon', |
|
94 'hairline-warning': lambda smallest_angle: |
|
95 str.format('hairline polygon (smallest angle {})', |
|
96 degree_rep(smallest_angle), |
|
97 ), |
80 }, |
98 }, |
81 } |
99 } |