Пример #1
0
    def get_intersection(self, segment):
        """
        Calculate the intersection of two line segments
        """

        _lhs = TupleMath.subtract(self.end, self.start)[0:2]
        _lhs = TupleMath.multiply(_lhs, (1.0, -1.0))

        _lhs += (sum(TupleMath.multiply(_lhs, self.start)),)

        _rhs = TupleMath.subtract(segment.end, segment.start)[0:2]
        _rhs = TupleMath.multiply(_lhs, (1.0, -1.0))

        _rhs += (sum(TupleMath.multiply(_rhs, segment.start)),)

        _determinant = TupleMath.cross(_lhs, _rhs, (0, 0, 1))[2]

        if not _determinant:
            return (math.nan, math.nan)

        _intersection = (
            TupleMath.cross(_lhs, _rhs, (1, 0, 0))[0],
            TupleMath.cross(_lhs, _rhs, (0, 1, 0))[1]
        )

        return TupleMath.scale(_intersection, 1.0 / _determinant)
Пример #2
0
    def project(self, displacement):
        """
        Project the point along the axis vector from the center
        displacement - distance from center
        """

        return TupleMath.add(self.center,
                             TupleMath.scale(self.vector, displacement))
Пример #3
0
    def set_length(self, length):
        """
        Set the axis length and update the axis end points
        """

        self.length = length

        _half_vector = TupleMath.scale(self.vector, self.length / 2.0)

        #set left (ccw) and right (cw) end points, respectively...
        self.end_points = (TupleMath.add(self.center, _half_vector),
                           TupleMath.subtract(self.center, _half_vector))
Пример #4
0
    def validate_datum(self):
        """
        Ensure the datum is valid, assuming 0+00 / (0,0,0)
        for station and coordinate where none is suplpied and it
        cannot be inferred fromt the starting geometry
        """
        _datum = self.data.get('meta')
        _geo = self.data.get('geometry')[0]

        if not _geo or not _datum:
            return

        _datum_truth = [
            not _datum.get('StartStation') is None,
            not _datum.get('Start') is None
        ]

        _geo_truth = [
            not _geo.get('StartStation') is None, not _geo.get('Start') is None
        ]

        #----------------------------
        #CASE 0
        #----------------------------
        #both defined?  nothing to do
        if all(_datum_truth):
            return

        #----------------------------
        #Parameter Initialization
        #----------------------------
        _geo_station = 0
        _geo_start = Vector()

        if _geo_truth[0]:
            _geo_station = _geo.get('StartStation')

        if _geo_truth[1]:
            _geo_start = _geo.get('Start')

        #---------------------
        #CASE 1
        #---------------------
        #no datum defined?  use initial geometry or zero defaults
        if not any(_datum_truth):

            _datum['StartStation'] = _geo_station
            _datum['Start'] = _geo_start
            return

        #--------------------
        #CASE 2
        #--------------------
        #station defined?
        #if the geometry has a station and coordinate,
        #project the start coordinate

        if _datum_truth[0]:

            _datum['Start'] = _geo_start

            #assume geometry start if no geometry station
            if not _geo_truth[0]:
                return

            #scale the distance to the system units
            delta = _geo_station - _datum['StartStation']

            #cutoff if error is below tolerance
            if not support.within_tolerance(delta):
                delta *= units.scale_factor()
            else:
                delta = 0.0

            #assume geometry start if station delta is zero
            if delta:

                #calculate the start based on station delta
                _datum['Start'] =\
                    TupleMath.subtract(_datum.get('Start'),
                    TupleMath.scale(
                        TupleMath.bearing_vector(_geo.get('BearingIn')),
                        delta)
                        #_geo.get('BearingIn')).multiply(delta)
                    )

            return

        #---------------------
        #CASE 3
        #---------------------
        #datum start coordinate is defined
        #if the geometry has station and coordinate,
        #project the start station
        _datum['StartStation'] = _geo_station

        #assume geometry station if no geometry start
        if _geo_truth[1]:

            #scale the length to the document units
            delta = TupleMath.length(
                TupleMath.subtract(
                    _geo_start, _datum.get('Start'))) / units.scale_factor()

            _datum['StartStation'] -= delta
Пример #5
0
    def update(self, angle):
        """
        Update the vehicle position using the given steering angle (radians)
        """

        # The angle subtended by the radius of the arc on which the front and
        # center wheel midpoints lie is equal to the steering angle.
        #
        # The radius is the distance between the axles divided by
        # the tangent of the steering angle
        #
        # The wheel angles are the arctangent of the axle distance divided by
        # the radius, offset by half the vehicle width.
        #
        # The arc direction is -cw / +ccw
        #
        # If the vehicle is towed (self.lead_vehicle is not None), angle is
        # ignored and calculations are performed using the lead vehicle
        # turning radius.

        _half_pi = math.pi / 2.0

        if abs(angle) > self.maximum_angle:
            return False

        self.axis.angle = angle
        self.radius = self.axle_distance / math.tan(angle)

        #sign of angle to add / subtract from central steering angle.
        #relative to ccw-oriented (left-hand) wheel
        _sign = 1.0  # math.copysign(1.0, angle)

        #get the index of the axle at the rear of the vehicle
        #(negative distance from the center)
        _back_axle = self.axle_dists.index(min(self.axle_dists))

        #get the axle centerpoint
        _back_center = self.axles[_back_axle].center

        #get the unit orthogonal of the back axle axis
        _back_vector = self.axles[_back_axle].ortho(_sign > 0.0)

        self.center = TupleMath.add(
            _back_center, TupleMath.scale(_back_vector, self.radius * -_sign))

        #iterate each wheel pair.  Left wheel is first in pair
        for _axle in self.axles:

            if _axle.is_fixed:
                continue

            #The wheel angle is the extra angle for each wheel
            #added to the central steering angle

            _wheel_angles = (_sign * self.axle_distance /
                             (self.radius + _axle.length / 2.0),
                             _sign * self.axle_distance /
                             (self.radius - _axle.length / 2.0))

            _axle.wheels[0].angle = math.atan(_wheel_angles[0])
            _axle.wheels[1].angle = math.atan(_wheel_angles[1])

        self.angle = angle

        return True