Exemple #1
0
    def set_basepoint(self):
        try:
            n = self.normal_vector
            c = self.constant_term
            base_point_coordinates = [0.0] * self.dimension

            initial_index = Line.first_nonzero_index(n)
            initial_coefficient = n[initial_index]

            base_point_coordinates[initial_index] = c / initial_coefficient
            self.base_point = Vector(base_point_coordinates)

        except Exception as e:
            if str(e) == Line.NO_NONZERO_ELTS_FOUND_MSG:
                self.base_point = None
            else:
                raise e
Exemple #2
0
    def get_intersection(self, ln):

        if self.normal_vector.is_zero() or ln.normal_vector.is_zero():
            return None

        if self.is_parallel(ln):
            if self.is_coincident(ln, True):
                raise Exception(self.COINCIDENT_VECTOR)
            else:
                return None
        a, b = self.normal_vector.coordinates
        c, d = ln.normal_vector.coordinates
        k1 = self.constant_term
        k2 = ln.constant_term
        base = a * d - b * c
        x = (d * k1 - b * k2) / base
        y = (-c * k1 + a * k2) / base
        return Vector([x, y])
Exemple #3
0
    def boundedMoveVertex(self, pos):
        index, shape = self.hVertex, self.hShape
        point = shape[index]
        if self.outOfPixmap(pos):
            size = self.pixmap.size()
            clipped_x = min(max(0, pos.x()), size.width())
            clipped_y = min(max(0, pos.y()), size.height())
            pos = QPointF(clipped_x, clipped_y)

        opposite_point_index = (index + 2) % 4
        o_to_pos_vector = Vector(shape[opposite_point_index], pos)
        o_to_prev_vector = Vector(shape[opposite_point_index],
                                  shape[(index + 3) % 4])
        o_to_next_vector = Vector(shape[opposite_point_index],
                                  shape[(index + 1) % 4])

        if self.drawSquare:
            opposite_point = shape[opposite_point_index]

            min_size = min(abs(pos.x() - opposite_point.x()),
                           abs(pos.y() - opposite_point.y()))
            directionX = -1 if pos.x() - opposite_point.x() < 0 else 1
            directionY = -1 if pos.y() - opposite_point.y() < 0 else 1
            shiftPos = QPointF(
                opposite_point.x() + directionX * min_size - point.x(),
                opposite_point.y() + directionY * min_size - point.y())
        else:
            o_to_pos_mag = o_to_pos_vector.magnitude()
            o_to_prev_mag = o_to_prev_vector.magnitude()
            o_to_next_mag = o_to_next_vector.magnitude()

            o_to_pos_u_vector = QPointF(o_to_pos_vector.x / o_to_pos_mag,
                                        o_to_pos_vector.y / o_to_pos_mag)
            o_to_prev_u_vector = QPointF(o_to_prev_vector.x / o_to_prev_mag,
                                         o_to_prev_vector.y / o_to_prev_mag)
            o_to_next_u_vector = QPointF(o_to_next_vector.x / o_to_next_mag,
                                         o_to_next_vector.y / o_to_next_mag)

            if o_to_pos_u_vector.x() == o_to_prev_u_vector.x(
            ) and o_to_pos_u_vector.y() == o_to_prev_u_vector.y():
                pos = pos + o_to_next_u_vector
            if o_to_pos_u_vector.x() == o_to_next_u_vector.x(
            ) and o_to_pos_u_vector.y() == o_to_next_u_vector.y():
                pos = pos + o_to_prev_u_vector

            shiftPos = pos - point

        point_to_pos_vector = Vector(point, pos)

        prev_proj = point_to_pos_vector.projection(o_to_prev_vector)
        next_proj = point_to_pos_vector.projection(o_to_next_vector)

        prev_shiftPos = QPointF(o_to_prev_vector.x * prev_proj,
                                o_to_prev_vector.y * prev_proj)
        next_shiftPos = QPointF(o_to_next_vector.x * next_proj,
                                o_to_next_vector.y * next_proj)

        shape.moveVertexBy(index, shiftPos)
        shape.moveVertexBy((index + 3) % 4, prev_shiftPos)
        shape.moveVertexBy((index + 1) % 4, next_shiftPos)
Exemple #4
0
class Line(object):

    NO_NONZERO_ELTS_FOUND_MSG = 'No nonzero elements found'
    COINCIDENT_VECTOR = 'Vector is coincident'

    dimension = 2
    normal_vector = Vector([0.0] * dimension)
    constant_term = 0.0
    base_point = None

    def __init__(self, normal_vector=None, constant_term=None):
        self.normal_vector = normal_vector
        self.constant_term = constant_term
        self.set_basepoint()

    def __eq__(self, other):
        if self.normal_vector.is_zero():
            if other.normal_vector.is_zero():
                return self.constant_term == other.constant_term
            else:
                return False
        elif other.normal_vector.is_zero():
            return False
        else:
            return self.is_coincident(other)

    def set_basepoint(self):
        try:
            n = self.normal_vector
            c = self.constant_term
            base_point_coordinates = [0.0] * self.dimension

            initial_index = Line.first_nonzero_index(n)
            initial_coefficient = n[initial_index]

            base_point_coordinates[initial_index] = c / initial_coefficient
            self.base_point = Vector(base_point_coordinates)

        except Exception as e:
            if str(e) == Line.NO_NONZERO_ELTS_FOUND_MSG:
                self.base_point = None
            else:
                raise e

    def is_parallel(self, ln):
        return self.normal_vector.is_parallel(ln.normal_vector)

    def get_intersection(self, ln):

        if self.normal_vector.is_zero() or ln.normal_vector.is_zero():
            return None

        if self.is_parallel(ln):
            if self.is_coincident(ln, True):
                raise Exception(self.COINCIDENT_VECTOR)
            else:
                return None
        a, b = self.normal_vector.coordinates
        c, d = ln.normal_vector.coordinates
        k1 = self.constant_term
        k2 = ln.constant_term
        base = a * d - b * c
        x = (d * k1 - b * k2) / base
        y = (-c * k1 + a * k2) / base
        return Vector([x, y])

    def is_coincident(self, ln, is_parallel_proven=False):
        if not is_parallel_proven:
            is_parallel_proven = self.is_parallel(ln)

        if not is_parallel_proven:
            return False

        two_base_points = self.base_point.minus(ln.base_point)
        return two_base_points.is_orthogonal(self.normal_vector)

    def __str__(self):

        num_decimal_places = 3

        def write_coefficient(coefficient, is_initial_term=False):
            coefficient = round(coefficient, num_decimal_places)
            if coefficient % 1 == 0:
                coefficient = int(coefficient)

            output = ''

            if coefficient < 0:
                output += '-'
            if coefficient > 0 and not is_initial_term:
                output += '+'

            if not is_initial_term:
                output += ' '

            if abs(coefficient) != 1:
                output += '{}'.format(abs(coefficient))

            return output

        n = self.normal_vector

        try:
            initial_index = Line.first_nonzero_index(n)
            terms = [
                write_coefficient(n[i], is_initial_term=(i == initial_index)) +
                'x_{}'.format(i + 1) for i in range(self.dimension)
                if round(n[i], num_decimal_places) != 0
            ]
            output = ' '.join(terms)

        except Exception as e:
            if str(e) == self.NO_NONZERO_ELTS_FOUND_MSG:
                output = '0'
            else:
                raise e

        constant = round(self.constant_term, num_decimal_places)
        if constant % 1 == 0:
            constant = int(constant)
        output += ' = {}'.format(constant)

        return output

    @staticmethod
    def first_nonzero_index(iterable):
        for k, item in enumerate(iterable):
            if not float_is_zero(item):
                return k
        raise Exception(Line.NO_NONZERO_ELTS_FOUND_MSG)
Exemple #5
0
from libs.vector import Vector
from libs.plane import Plane
from libs.linsys import LinearSystem

p0 = Plane(normal_vector=Vector([1, 1, 1]), constant_term=1)
p1 = Plane(normal_vector=Vector([0, 1, 0]), constant_term=2)
p2 = Plane(normal_vector=Vector([1, 1, -1]), constant_term=3)
p3 = Plane(normal_vector=Vector([1, 0, -2]), constant_term=2)

s = LinearSystem([p0, p1, p2, p3])
s.swap_rows(0, 1)
if not (s[0] == p1 and s[1] == p0 and s[2] == p2 and s[3] == p3):
    print('test case 1 failed')

s.swap_rows(1, 3)
if not (s[0] == p1 and s[1] == p3 and s[2] == p2 and s[3] == p0):
    print('test case 2 failed')

s.swap_rows(3, 1)
if not (s[0] == p1 and s[1] == p0 and s[2] == p2 and s[3] == p3):
    print('test case 3 failed')

s.multiply_coefficient_and_row(1, 0)
if not (s[0] == p1 and s[1] == p0 and s[2] == p2 and s[3] == p3):
    print('test case 4 failed')

s.multiply_coefficient_and_row(-1, 2)
if not (s[0] == p1 and s[1] == p0 and s[2] == Plane(
        normal_vector=Vector([-1, -1, 1]), constant_term=-3) and s[3] == p3):
    print('test case 5 failed')
Exemple #6
0
class Plane(object):

    NO_NONZERO_ELTS_FOUND_MSG = 'No nonzero elements found'

    dimension = 3
    normal_vector = Vector([0.0] * dimension)
    constant_term = 0.0
    basepoint = Vector([0.0] * dimension)

    def __init__(self, normal_vector=None, constant_term=None):
        if normal_vector:
            self.normal_vector = normal_vector
        if constant_term:
            self.constant_term = constant_term
        self.set_basepoint()

    def set_basepoint(self):
        try:
            n = self.normal_vector
            c = self.constant_term
            basepoint_coords = [0.0] * self.dimension

            initial_index = Plane.first_nonzero_index(n)
            initial_coefficient = n[initial_index]

            basepoint_coords[initial_index] = c / initial_coefficient
            self.basepoint = Vector(basepoint_coords)

        except Exception as e:
            if str(e) == Plane.NO_NONZERO_ELTS_FOUND_MSG:
                self.basepoint = None
            else:
                raise e

    def __str__(self):
        num_decimal_places = 3

        def write_coefficient(coefficient, is_initial_term=False):
            coefficient = round(coefficient, num_decimal_places)
            if coefficient % 1 == 0:
                coefficient = int(coefficient)

            output = ''

            if coefficient < 0:
                output += '-'
            if coefficient > 0 and not is_initial_term:
                output += '+'

            if not is_initial_term:
                output += ' '

            if abs(coefficient) != 1:
                output += '{}'.format(abs(coefficient))

            return output

        n = self.normal_vector

        try:
            initial_index = Plane.first_nonzero_index(n)
            terms = [
                write_coefficient(n[i], is_initial_term=(i == initial_index)) +
                'x_{}'.format(i + 1) for i in range(self.dimension)
                if round(n[i], num_decimal_places) != 0
            ]
            output = ' '.join(terms)

        except Exception as e:
            if str(e) == self.NO_NONZERO_ELTS_FOUND_MSG:
                output = '0'
            else:
                raise e

        constant = round(self.constant_term, num_decimal_places)
        if constant % 1 == 0:
            constant = int(constant)
        output += ' = {}'.format(constant)

        return output

    def is_parallel(self, pl):
        return self.normal_vector.is_parallel(pl.normal_vector)

    def __eq__(self, other):
        if self.normal_vector.is_zero():
            if other.normal_vector.is_zero():
                return self.constant_term == other.constant_term
            else:
                return False
        elif other.normal_vector.is_zero():
            return False
        elif not self.is_parallel(other):
            return False
        else:
            test_vector = self.basepoint.minus(other.basepoint)
            return test_vector.is_orthogonal(self.normal_vector)

    @staticmethod
    def first_nonzero_index(iterable):
        for k, item in enumerate(iterable):
            if not float_is_zero(item):
                return k
        raise Exception(Plane.NO_NONZERO_ELTS_FOUND_MSG)