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 def transform_to_xy(geometry): |
|
10 a, b, c = geometry.vertices[:3] |
|
11 |
|
12 |
|
13 def concave_test(model): |
9 def concave_test(model): |
14 for quadrilateral in model.quadrilaterals: |
10 for quadrilateral in model.quadrilaterals: |
15 print([cross_product(v2 - v1, v3 - v1) for v1, v2, v3 in pairs(quadrilateral.geometry.vertices, count = 3)]) |
11 geometry = transform_to_xy(quadrilateral.geometry) |
16 z_scores = [ |
12 z_scores = [ |
17 cross_product(v2 - v1, v3 - v1).z |
13 cross_product(v2 - v1, v3 - v1).z |
18 for v1, v2, v3 in pairs(quadrilateral.geometry.vertices, count = 3) |
14 for v1, v2, v3 in pairs(geometry.vertices, count = 3) |
19 ] |
15 ] |
20 print(z_scores) |
|
21 if not sign_consistency(z_scores): |
16 if not sign_consistency(z_scores): |
22 yield warning(quadrilateral, 'Concave quadrilateral') |
17 yield error(quadrilateral, 'Concave quadrilateral') |
23 |
18 |
24 def bowtie_quadrilateral_test(model): |
19 def bowtie_quadrilateral_test(model): |
25 for quadrilateral in model.quadrilaterals: |
20 ... |
26 vertices = IndexRing(quadrilateral.geometry.vertices) |
|
27 for i in (0, 1): |
|
28 line1 = LineSegment(vertices[0 + i], vertices[1 + i]) |
|
29 line2 = LineSegment(vertices[2 + i], vertices[3 + i]) |
|
30 try: |
|
31 line_intersection(line1, line2) |
|
32 except NoIntersection: |
|
33 pass |
|
34 else: |
|
35 yield error(quadrilateral, 'Bowtie quadrilateral') |
|
36 break |
|
37 |
|
38 def vector_angle(vec_1, vec_2, normalized = False): |
|
39 cosine = dot_product(vec_1, vec_2) |
|
40 try: |
|
41 cosine /= vec_1.length() * vec_2.length() |
|
42 except ZeroDivisionError: |
|
43 return 0 |
|
44 angle = acos(cosine) |
|
45 if normalized and angle > π / 2: |
|
46 angle = π - angle |
|
47 return angle |
|
48 |
21 |
49 def skew_test(model): |
22 def skew_test(model): |
50 for quadrilateral in model.quadrilaterals: |
23 for quadrilateral in model.quadrilaterals: |
51 vertices = IndexRing(quadrilateral.geometry.vertices) |
24 for triangles in split_quadrilateral(quadrilateral.geometry): |
52 for i in (0, 1): |
25 plane_1 = triangle_plane_normal(triangles[0]) |
53 a, b = vertices[0 + i], vertices[1 + i] |
26 plane_2 = triangle_plane_normal(triangles[1]) |
54 c, d = vertices[2 + i], vertices[3 + i] |
|
55 plane_1 = cross_product(b - a, d - a) |
|
56 plane_2 = cross_product(d - c, b - c) |
|
57 angle = vector_angle(plane_1, plane_2, normalized = True) |
27 angle = vector_angle(plane_1, plane_2, normalized = True) |
58 if angle > radians(0.1): |
28 if angle > radians(0.1): |
59 yield error(quadrilateral, |
29 yield error(quadrilateral, |
60 'Skew quadrilateral (plane angle {}°)', |
30 'Skew quadrilateral (plane angle {}°)', |
61 '%.3f' % degrees(angle)) |
31 '%.3f' % degrees(angle)) |
62 break |
32 break |
|
33 |
|
34 manifest = { |
|
35 'tests': {skew_test, concave_test}, |
|
36 } |