Wed, 24 Jan 2018 23:14:01 +0200
Fix math domain errors in vector_angle
22 | 1 | from math import radians |
13 | 2 | from testsuite import warning, error |
12 | 3 | from geometry import * |
4 | ||
5 | def sign_consistency(container): | |
6 | # Returns whether all elements in container have the same sign | |
7 | return min(container) * max(container) >= 0 | |
8 | ||
9 | def concave_test(model): | |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
22
diff
changeset
|
10 | ''' Checks that all quadrilaterals are convex. ''' |
13 | 11 | for quadrilateral in model.quadrilaterals: |
28 | 12 | # Rotate the polygon into the XY plane. Then z is facing |
13 | # away from the quadrilateral. | |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
14 | geometry = transform_to_xy(quadrilateral.geometry) |
28 | 15 | # Now do a 2D concavity test: |
16 | # https://math.stackexchange.com/a/1745427 | |
12 | 17 | z_scores = [ |
18 | cross_product(v2 - v1, v3 - v1).z | |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
19 | for v1, v2, v3 in pairs(geometry.vertices, count = 3) |
12 | 20 | ] |
21 | if not sign_consistency(z_scores): | |
16 | 22 | yield error(quadrilateral, 'concave-error') |
13 | 23 | |
24 | def skew_test(model): | |
26
7c263b864371
Added command line option to list all checks.
Santeri Piippo
parents:
22
diff
changeset
|
25 | ''' Checks that all quadrilaterals are coplanar. ''' |
13 | 26 | for quadrilateral in model.quadrilaterals: |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
27 | for triangles in split_quadrilateral(quadrilateral.geometry): |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
28 | plane_1 = triangle_plane_normal(triangles[0]) |
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
29 | plane_2 = triangle_plane_normal(triangles[1]) |
16 | 30 | skew_angle = vector_angle(plane_1, plane_2, normalized = True) |
27
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
31 | if skew_angle > radians(3.0): |
16 | 32 | yield error(quadrilateral, 'skew-error', |
33 | skew_angle = skew_angle, | |
34 | ) | |
13 | 35 | break |
27
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
36 | elif skew_angle > radians(1.0): |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
37 | yield warning(quadrilateral, 'skew-warning', |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
38 | skew_angle = skew_angle, |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
39 | ) |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
40 | break |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
41 | |
28 | 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 | ||
30
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
54 | def collinear_test(model): |
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
55 | for element in model.body: |
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
56 | if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
57 | for a, b, c in pairs(element.geometry.vertices, count = 3): |
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
58 | if cross_product(b - a, c - a).length() < 1e-5: |
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
59 | yield error(element, 'collinearity-error') |
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
60 | |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
61 | manifest = { |
16 | 62 | 'tests': { |
63 | 'skew': skew_test, | |
64 | 'concave': concave_test, | |
28 | 65 | 'bowtie': bowtie_test, |
30
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
66 | 'collinearity': collinear_test, |
16 | 67 | }, |
68 | 'messages': { | |
69 | 'skew-error': lambda skew_angle: | |
22 | 70 | str.format('skew quadrilateral (plane angle {})', |
71 | degree_rep(skew_angle), | |
16 | 72 | ), |
27
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
73 | 'skew-warning': lambda skew_angle: |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
74 | str.format('slightly skew quadrilateral (plane angle {})', |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
75 | degree_rep(skew_angle), |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
76 | ), |
18 | 77 | 'concave-error': 'concave quadrilateral', |
28 | 78 | 'self-intersecting': 'bowtie quadrilateral', |
30
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
79 | 'collinearity-error': 'collinear polygon', |
16 | 80 | }, |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
81 | } |