12 z_scores = [ |
12 z_scores = [ |
13 cross_product(v2 - v1, v3 - v1).z |
13 cross_product(v2 - v1, v3 - v1).z |
14 for v1, v2, v3 in pairs(geometry.vertices, count = 3) |
14 for v1, v2, v3 in pairs(geometry.vertices, count = 3) |
15 ] |
15 ] |
16 if not sign_consistency(z_scores): |
16 if not sign_consistency(z_scores): |
17 yield error(quadrilateral, 'Concave quadrilateral') |
17 yield error(quadrilateral, 'concave-error') |
18 |
|
19 def bowtie_quadrilateral_test(model): |
|
20 ... |
|
21 |
18 |
22 def skew_test(model): |
19 def skew_test(model): |
|
20 ''' Test for non-coplanar quadrilaterals. ''' |
23 for quadrilateral in model.quadrilaterals: |
21 for quadrilateral in model.quadrilaterals: |
24 for triangles in split_quadrilateral(quadrilateral.geometry): |
22 for triangles in split_quadrilateral(quadrilateral.geometry): |
25 plane_1 = triangle_plane_normal(triangles[0]) |
23 plane_1 = triangle_plane_normal(triangles[0]) |
26 plane_2 = triangle_plane_normal(triangles[1]) |
24 plane_2 = triangle_plane_normal(triangles[1]) |
27 angle = vector_angle(plane_1, plane_2, normalized = True) |
25 skew_angle = vector_angle(plane_1, plane_2, normalized = True) |
28 if angle > radians(0.1): |
26 if skew_angle > radians(0.1): |
29 yield error(quadrilateral, |
27 yield error(quadrilateral, 'skew-error', |
30 'Skew quadrilateral (plane angle {}°)', |
28 skew_angle = skew_angle, |
31 '%.3f' % degrees(angle)) |
29 ) |
32 break |
30 break |
33 |
31 |
34 manifest = { |
32 manifest = { |
35 'tests': {skew_test, concave_test}, |
33 'tests': { |
|
34 'skew': skew_test, |
|
35 'concave': concave_test, |
|
36 }, |
|
37 'messages': { |
|
38 'skew-error': lambda skew_angle: |
|
39 str.format('Skew quadrilateral (plane angle {}°)', |
|
40 '%.2f' % degrees(skew_angle), |
|
41 ), |
|
42 'concave-error': 'Concave quadrilateral', |
|
43 }, |
36 } |
44 } |