Exemplo n.º 1
0
    def distance_from_location_using_u_v_w(cls, u=None, v=None, w=None, timestep=None, location=None):
        """
            Calculate the greate distance from a location using u, v, and w.

            u, v, and w must be in the same units as the timestep.  Stick with seconds.

        """
        # Move horizontally
        distance_horiz = 0
        azimuth = 0
        angle = 0
        depth = location.depth

        if u is not 0 and v is not 0:
            s_and_d = AsaMath.speed_direction_from_u_v(u=u,v=v) # calculates velocity in m/s from transformed u and v
            distance_horiz = s_and_d['speed'] * timestep # calculate the horizontal distance in meters using the velocity and model timestep
            angle = s_and_d['direction']
            # Great circle calculation 
            # Calculation takes in azimuth (heading from North, so convert our mathematical angle to azimuth)
            azimuth = AsaMath.math_angle_to_azimuth(angle=angle)
            
        distance_vert = 0.
        if w is not None:
            # Move vertically
            # Depth is positive up, negative down.  w wil be negative if moving down, and positive if moving up
            distance_vert = w * timestep
            depth += distance_vert # calculate the vertical distance in meters using w (m/s) and model timestep (s)
            

        if distance_horiz != 0:
            vertical_angle = math.degrees(math.atan(distance_vert / distance_horiz))
            gc_result = AsaGreatCircle.great_circle(distance=distance_horiz, azimuth=azimuth, start_point=location) 
        else:
            # Did we go up or down?
            vertical_angle = 0.
            if distance_vert < 0:
                # Down
                vertical_angle = 270.
            elif distance_vert > 0:
                # Up
                vertical_angle = 90.
            gc_result = { 'latitude': location.latitude, 'longitude': location.longitude, 'reverse_azimuth': 0 }
            
        #logger.info("Particle moving from %fm to %fm from a vertical speed of %f m/s over %s seconds" % (location.depth, depth, w, str(timestep)))            
        gc_result['azimuth'] = azimuth
        gc_result['depth'] = depth
        gc_result['distance'] = distance_horiz
        gc_result['angle'] = angle
        gc_result['vertical_distance'] = distance_vert
        gc_result['vertical_angle'] = vertical_angle
        return gc_result
Exemplo n.º 2
0
    def __bounce(self, **kwargs):
        """
            Bounce off of the shoreline.

            NOTE: This does not work, but left here for future implementation

            feature = Linestring of two points, being the line segment the particle hit.
            angle = decimal degrees from 0 (x-axis), couter-clockwise (math style)
        """
        start_point = kwargs.pop('start_point')
        hit_point = kwargs.pop('hit_point')
        end_point = kwargs.pop('end_point')
        feature = kwargs.pop('feature')
        distance = kwargs.pop('distance')
        angle = kwargs.pop('angle')

        # Figure out the angle of the shoreline here (beta)
        points_in_shore = map(lambda x: Point(x), list(feature.coords))
        points_in_shore = sorted(points_in_shore, key=lambda x: x.x)

        # The point on the left (least longitude is always the first Point)
        first_shore = points_in_shore[0]
        last_shore = points_in_shore[-1]

        shoreline_x = abs(abs(first_shore.x) - abs(last_shore.x))
        shoreline_y = abs(abs(first_shore.y) - abs(last_shore.y))
        beta = math.degrees(math.atan(shoreline_x / shoreline_y))

        theta = 90 - angle - beta
        bounce_azimuth = AsaMath.math_angle_to_azimuth(angle=2 * theta + angle)

        print "Beta:           " + str(beta)
        print "Incoming Angle: " + str(angle)
        print "ShorelineAngle: " + str(theta + angle)
        print "Bounce Azimuth: " + str(bounce_azimuth)
        print "Bounce Angle:   " + str(
            AsaMath.azimuth_to_math_angle(azimuth=bounce_azimuth))

        after_distance = distance - AsaGreatCircle.great_distance(
            start_point=start_point, end_point=hit_point)['distance']

        new_point = AsaGreatCircle.great_circle(distance=after_distance,
                                                azimuth=bounce_azimuth,
                                                start_point=hit_point)
        return Location4D(latitude=new_point['latitude'],
                          longitude=new_point['longitude'],
                          depth=start_point.depth)
Exemplo n.º 3
0
    def __bounce(self, **kwargs):
        """
            Bounce off of the shoreline.

            NOTE: This does not work, but left here for future implementation

            feature = Linestring of two points, being the line segment the particle hit.
            angle = decimal degrees from 0 (x-axis), couter-clockwise (math style)
        """
        start_point = kwargs.pop("start_point")
        hit_point = kwargs.pop("hit_point")
        end_point = kwargs.pop("end_point")
        feature = kwargs.pop("feature")
        distance = kwargs.pop("distance")
        angle = kwargs.pop("angle")

        # Figure out the angle of the shoreline here (beta)
        points_in_shore = map(lambda x: Point(x), list(feature.coords))
        points_in_shore = sorted(points_in_shore, key=lambda x: x.x)

        # The point on the left (least longitude is always the first Point)
        first_shore = points_in_shore[0]
        last_shore = points_in_shore[-1]

        shoreline_x = abs(abs(first_shore.x) - abs(last_shore.x))
        shoreline_y = abs(abs(first_shore.y) - abs(last_shore.y))
        beta = math.degrees(math.atan(shoreline_x / shoreline_y))

        theta = 90 - angle - beta
        bounce_azimuth = AsaMath.math_angle_to_azimuth(angle=2 * theta + angle)

        print "Beta:           " + str(beta)
        print "Incoming Angle: " + str(angle)
        print "ShorelineAngle: " + str(theta + angle)
        print "Bounce Azimuth: " + str(bounce_azimuth)
        print "Bounce Angle:   " + str(AsaMath.azimuth_to_math_angle(azimuth=bounce_azimuth))

        after_distance = (
            distance - AsaGreatCircle.great_distance(start_point=start_point, end_point=hit_point)["distance"]
        )

        new_point = AsaGreatCircle.great_circle(distance=after_distance, azimuth=bounce_azimuth, start_point=hit_point)
        return Location4D(latitude=new_point["latitude"], longitude=new_point["longitude"], depth=start_point.depth)
Exemplo n.º 4
0
    def test_math_angle_to_geo(self):
        azimuth = AsaMath.math_angle_to_azimuth(angle=90)
        assert azimuth == 0

        azimuth = AsaMath.math_angle_to_azimuth(angle=180)
        assert azimuth == 270

        azimuth = AsaMath.math_angle_to_azimuth(angle=0)
        assert azimuth == 90

        azimuth = AsaMath.math_angle_to_azimuth(angle=360)
        assert azimuth == 90

        azimuth = AsaMath.math_angle_to_azimuth(angle=270)
        assert azimuth == 180

        azimuth = AsaMath.math_angle_to_azimuth(angle=45)
        assert azimuth == 45

        azimuth = AsaMath.math_angle_to_azimuth(angle=232)
        assert azimuth == 218

        azimuth = AsaMath.math_angle_to_azimuth(angle=45)
        assert azimuth == 45
Exemplo n.º 5
0
    def test_math_angle_to_geo(self):
        azimuth = AsaMath.math_angle_to_azimuth(angle=90)
        assert azimuth == 0

        azimuth = AsaMath.math_angle_to_azimuth(angle=180)
        assert azimuth == 270

        azimuth = AsaMath.math_angle_to_azimuth(angle=0)
        assert azimuth == 90

        azimuth = AsaMath.math_angle_to_azimuth(angle=360)
        assert azimuth == 90

        azimuth = AsaMath.math_angle_to_azimuth(angle=270)
        assert azimuth == 180

        azimuth = AsaMath.math_angle_to_azimuth(angle=45)
        assert azimuth == 45

        azimuth = AsaMath.math_angle_to_azimuth(angle=232)
        assert azimuth == 218

        azimuth = AsaMath.math_angle_to_azimuth(angle=45)
        assert azimuth == 45