예제 #1
0
    def test_radians(self):
        """test_radians doc..."""
        for i in range(100):
            value = random.uniform(-2000.0, 5000.0)
            a = angle.Angle(radians=value)
            self.assertAlmostEqual(a.radians, value)

        for i in range(100):
            value = random.uniform(-2000.0, 5000.0)
            a = angle.Angle()
            a.radians = value
            self.assertAlmostEqual(a.radians, value)
예제 #2
0
    def test_differenceBetween(self):
        """test_differenceBetween doc..."""

        for i in range(1000):
            value = random.uniform(-2000.0, 5000.0)
            a = angle.Angle(degrees=value)
            a.constrain_to_revolution()

            value = random.uniform(-2000.0, 5000.0)
            b = angle.Angle(degrees=value)
            b.constrain_to_revolution()
            self.assertLessEqual(abs(a.difference_between(b).degrees), 180.0)
예제 #3
0
    def test_degrees(self):
        """ doc... """
        for i in range(100):
            value = random.uniform(-2000.0, 5000.0)
            a = angle.Angle(degrees=value)
            self.assertAlmostEqual(a.degrees, value)

        for i in range(100):
            value = random.uniform(-2000.0, 5000.0)
            a = angle.Angle()
            a.degrees = value
            self.assertAlmostEqual(a.degrees, value)
예제 #4
0
    def test_constrainToRevolution(self):
        """test_revolvePositive doc..."""

        for i in range(100):
            value = random.uniform(-2000.0, 5000.0)
            a = angle.Angle(degrees=value)
            a.constrain_to_revolution()
            self.assertLessEqual(a.degrees, 360.0)
            self.assertGreaterEqual(a.degrees, 0.0)
예제 #5
0
    def test_rotate(self):
        tests = [(90.0, 0.0, 1.0), (-90.0, 0.0, -1.0), (180.0, -1.0, 0.0),
                 (-180.0, -1.0, 0.0), (270.0, 0.0, -1.0), (-270.0, 0.0, 1.0),
                 (360.0, 1.0, 0.0), (-360.0, 1.0, 0.0),
                 (45.0, HALF_SQRT_2, HALF_SQRT_2),
                 (-45.0, HALF_SQRT_2, -HALF_SQRT_2),
                 (315.0, HALF_SQRT_2, -HALF_SQRT_2),
                 (-315.0, HALF_SQRT_2, HALF_SQRT_2), (30.0, HALF_SQRT_3, 0.5),
                 (-30.0, HALF_SQRT_3, -0.5), (330.0, HALF_SQRT_3, -0.5),
                 (-330.0, HALF_SQRT_3, 0.5)]

        for test in tests:
            radius = random.uniform(0.001, 1000.0)
            p = value2D.Point2D(value.ValueUncertainty(radius, 0.25),
                                value.ValueUncertainty(0.0, 0.25))

            p.rotate(angle.Angle(degrees=test[0]))
            self.assertAlmostEqual(p.x.raw, radius * test[1], 2)
            self.assertAlmostEqual(p.y.raw, radius * test[2], 2)
예제 #6
0
    def angle_between(self, point):
        """

        :param point:
        :return:
        """

        my_length = self.length
        pos_length = point.length
        numerator = self.x*point.x + self.y*point.y
        denominator = my_length * pos_length

        if value.equivalent(denominator.value, 0.0, 1e-6):
            return angle.Angle(radians=0.0, uncertainty=0.5*math.pi)

        result = numerator/denominator

        if value.equivalent(result.value, 1.0, 1e-5):
            return angle.Angle()

        try:
            if value.equivalent(result.value, -1.0, 1e-5):
                a = math.pi
            else:
                a = math.acos(result.raw)
        except Exception:
            print('[ERROR]: Unable to calculate angle between', result)
            return angle.Angle()

        if value.equivalent(a, math.pi, 1e-5):
            return angle.Angle(radians=a, uncertainty_degrees=180.0)

        try:
            aUnc = abs(1.0 / (1.0 - result.raw * result.raw) ** 0.5) * \
                   result.raw_uncertainty
        except Exception as err:
            print('[ERROR]: Unable to calculate angle between uncertainty',
                  result, a)
            return angle.Angle()

        return angle.Angle(radians=a, uncertainty=aUnc)
예제 #7
0
def closest_point_on_line(point, line_start, line_end, contained=True):
    """
    Finds the closest point on a line to the specified point using the formulae
    discussed in the "another formula" section of:

        wikipedia.org/wiki/Distance_from_a_point_to_a_line#Another_formula
    """

    length = line_start.distance_from(line_end)
    if not length:
        raise ValueError('Cannot calculate point. Invalid line segment.')

    s = line_start
    e = line_end
    delta_x = e.x.raw - s.x.raw
    delta_y = e.y.raw - s.y.raw
    rotate = False
    slope = 0.0
    slope_unc = 0.0

    try:
        slope = delta_y / delta_x
        slope_unc = (
            abs(1.0 / delta_x) * (
                s.y.raw_uncertainty + e.y.raw_uncertainty
            ) + abs(
                slope / delta_x
            ) * (
                s.x.raw_uncertainty + e.x.raw_uncertainty
            )
        )
    except Exception:
        rotate = True
        raise

    if rotate or (abs(slope) > 1.0 and abs(slope_unc / slope) > 0.5):
        a = angle.Angle(degrees=20.0)
        e2 = e.clone().rotate(a, s)
        p2 = point.clone().rotate(a, s)
        print(point, p2)
        print(e, e2)
        result = closest_point_on_line(p2, s, e2, contained)
        if result is None:
            return result

        a.degrees = -20.0
        result.rotate(a, s)
        return result

    intercept = s.y.raw - slope * s.x.raw
    denom = slope * slope + 1.0
    numer = point.x.raw + slope * (point.y.raw - intercept)

    x = numer / denom
    y = (slope * numer) / denom + intercept

    if contained:
        # Check to see if point is between start and end values
        x_range = sorted([s.x.raw, e.x.raw])
        y_range = sorted([s.y.raw, e.y.raw])
        eps = 1e-8
        x_min = x - eps
        x_max = x + eps
        y_min = y - eps
        y_max = y + eps

        out_of_bounds = (
            x_range[1] < x_min or
            x_max < x_range[0] or
            y_range[1] < y_min or
            y_max < y_range[0]
        )
        if out_of_bounds:
            return None

    start_dist = ops.sqrt_sum_of_squares(s.x.raw - x, s.y.raw - y)
    end_dist = ops.sqrt_sum_of_squares(e.x.raw - x, e.y.raw - y)

    x_unc = (
        start_dist / length.raw * s.x.raw_uncertainty +
        end_dist / length.raw * e.x.raw_uncertainty
    )
    x_unc = math.sqrt(x_unc ** 2 + point.x.raw_uncertainty ** 2)

    y_unc = (
        start_dist / length.raw * s.y.raw_uncertainty +
        end_dist / length.raw * e.y.raw_uncertainty
    )
    y_unc = math.sqrt(y_unc ** 2 + point.y.raw_uncertainty ** 2)

    return create_point(x=x, y=y, x_unc=x_unc, y_unc=y_unc)