tests/quadrilaterals.py

Tue, 23 Jan 2018 14:09:44 +0200

author
Santeri Piippo
date
Tue, 23 Jan 2018 14:09:44 +0200
changeset 28
5933250813a3
parent 27
3089611c99d1
child 30
0d9ca37901ed
permissions
-rw-r--r--

Added bowtie check

from math import radians
from testsuite import warning, error
from geometry import *

def sign_consistency(container):
    # Returns whether all elements in container have the same sign
    return min(container) * max(container) >= 0

def concave_test(model):
    ''' Checks that all quadrilaterals are convex. '''
    for quadrilateral in model.quadrilaterals:
        # Rotate the polygon into the XY plane. Then z is facing
        # away from the quadrilateral.
        geometry = transform_to_xy(quadrilateral.geometry)
        # Now do a 2D concavity test:
        # https://math.stackexchange.com/a/1745427
        z_scores = [
            cross_product(v2 - v1, v3 - v1).z
            for v1, v2, v3 in pairs(geometry.vertices, count = 3)
        ]
        if not sign_consistency(z_scores):
            yield error(quadrilateral, 'concave-error')

def skew_test(model):
    ''' Checks that all quadrilaterals are coplanar. '''
    for quadrilateral in model.quadrilaterals:
        for triangles in split_quadrilateral(quadrilateral.geometry):
            plane_1 = triangle_plane_normal(triangles[0])
            plane_2 = triangle_plane_normal(triangles[1])
            skew_angle = vector_angle(plane_1, plane_2, normalized = True)
            if skew_angle > radians(3.0):
                yield error(quadrilateral, 'skew-error',
                    skew_angle = skew_angle,
                )
                break
            elif skew_angle > radians(1.0):
                yield warning(quadrilateral, 'skew-warning',
                    skew_angle = skew_angle,
                )
                break

def bowtie_test(model):
    for quadrilateral in model.quadrilaterals:
        geometry = transform_to_xy(quadrilateral.geometry)
        vertices = IndexRing(geometry.vertices)
        for i in (0, 1):
            line_1 = LineSegment(vertices[0 + i], vertices[1 + i])
            line_2 = LineSegment(vertices[2 + i], vertices[3 + i])
            intersection = line_segment_intersection_xy(line_1, line_2)
            if intersection:
                yield error(quadrilateral, 'self-intersecting')
                break

manifest = {
    'tests': {
        'skew': skew_test,
        'concave': concave_test,
        'bowtie': bowtie_test,
    },
    'messages': {
        'skew-error': lambda skew_angle:
            str.format('skew quadrilateral (plane angle {})',
                degree_rep(skew_angle),
            ),
        'skew-warning': lambda skew_angle:
            str.format('slightly skew quadrilateral (plane angle {})',
                degree_rep(skew_angle),
            ),
        'concave-error': 'concave quadrilateral',
        'self-intersecting': 'bowtie quadrilateral',
    },
}

mercurial