--- a/tests/concave.py Fri Jan 19 13:41:23 2018 +0200 +++ b/tests/concave.py Sun Jan 21 15:03:38 2018 +0200 @@ -1,5 +1,5 @@ -from math import degrees, pi as π -from testsuite import warning +from math import acos, degrees, radians, pi as π +from testsuite import warning, error from geometry import * def sign_consistency(container): @@ -11,7 +11,7 @@ def concave_test(model): - for quadrilateral in model: + for quadrilateral in model.quadrilaterals: print([cross_product(v2 - v1, v3 - v1) for v1, v2, v3 in pairs(quadrilateral.geometry.vertices, count = 3)]) z_scores = [ cross_product(v2 - v1, v3 - v1).z @@ -19,4 +19,44 @@ ] print(z_scores) if not sign_consistency(z_scores): - yield warning(quadrilateral, 'Concave quadrilateral') \ No newline at end of file + yield warning(quadrilateral, 'Concave quadrilateral') + +def bowtie_quadrilateral_test(model): + for quadrilateral in model.quadrilaterals: + vertices = IndexRing(quadrilateral.geometry.vertices) + for i in (0, 1): + line1 = LineSegment(vertices[0 + i], vertices[1 + i]) + line2 = LineSegment(vertices[2 + i], vertices[3 + i]) + try: + line_intersection(line1, line2) + except NoIntersection: + pass + else: + yield error(quadrilateral, 'Bowtie quadrilateral') + break + +def vector_angle(vec_1, vec_2, normalized = False): + cosine = dot_product(vec_1, vec_2) + try: + cosine /= vec_1.length() * vec_2.length() + except ZeroDivisionError: + return 0 + angle = acos(cosine) + if normalized and angle > π / 2: + angle = π - angle + return angle + +def skew_test(model): + for quadrilateral in model.quadrilaterals: + vertices = IndexRing(quadrilateral.geometry.vertices) + for i in (0, 1): + a, b = vertices[0 + i], vertices[1 + i] + c, d = vertices[2 + i], vertices[3 + i] + plane_1 = cross_product(b - a, d - a) + plane_2 = cross_product(d - c, b - c) + angle = vector_angle(plane_1, plane_2, normalized = True) + if angle > radians(0.1): + yield error(quadrilateral, + 'Skew quadrilateral (plane angle {}°)', + '%.3f' % degrees(angle)) + break