Fri, 24 May 2019 14:20:18 +0200
now checks that paths are specified
22 | 1 | from math import radians |
32
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
2 | from testsuite import warning, error, notice |
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 | |
32
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
61 | def hairline_score(smallest_angle): |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
62 | from math import log10 |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
63 | return max(0, -log10(smallest_angle)) |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
64 | |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
65 | def hairline_test(model): |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
66 | for element in model.body: |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
67 | if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
68 | smallest_angle = element.geometry.smallest_angle |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
69 | if smallest_angle < radians(0.5): |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
70 | yield notice(element, 'hairline-warning', |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
71 | smallest_angle = smallest_angle, |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
72 | ) |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
73 | |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
74 | manifest = { |
16 | 75 | 'tests': { |
76 | 'skew': skew_test, | |
77 | 'concave': concave_test, | |
28 | 78 | 'bowtie': bowtie_test, |
30
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
79 | 'collinearity': collinear_test, |
32
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
80 | 'hairline': hairline_test, |
16 | 81 | }, |
82 | 'messages': { | |
83 | 'skew-error': lambda skew_angle: | |
22 | 84 | str.format('skew quadrilateral (plane angle {})', |
85 | degree_rep(skew_angle), | |
16 | 86 | ), |
27
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
87 | 'skew-warning': lambda skew_angle: |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
88 | str.format('slightly skew quadrilateral (plane angle {})', |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
89 | degree_rep(skew_angle), |
3089611c99d1
Changed threshold skew test, added warning for slightly skew quads
Santeri Piippo
parents:
26
diff
changeset
|
90 | ), |
18 | 91 | 'concave-error': 'concave quadrilateral', |
28 | 92 | 'self-intersecting': 'bowtie quadrilateral', |
30
0d9ca37901ed
added test for collinearity, fixed bowtie test
Santeri Piippo
parents:
28
diff
changeset
|
93 | 'collinearity-error': 'collinear polygon', |
32
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
94 | 'hairline-warning': lambda smallest_angle: |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
95 | str.format('hairline polygon (smallest angle {})', |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
96 | degree_rep(smallest_angle), |
75f44d3063da
Reworked web front, problems are now sorted by category as well as line number
Santeri Piippo
parents:
30
diff
changeset
|
97 | ), |
16 | 98 | }, |
14
d383f319f35b
transform_to_xy implemented and concave test online
Santeri Piippo
parents:
13
diff
changeset
|
99 | } |