Beispiel #1
0
def _normalize(p1, p2, p3):
    """ Return feature parts for a trio of points - re-ordered points, ratio, theta.
    """
    h12 = _hypot(p2.x - p1.x, p2.y - p1.y)
    h13 = _hypot(p3.x - p1.x, p3.y - p1.y)
    h23 = _hypot(p3.x - p2.x, p3.y - p2.y)
    
    hs = sorted([h12, h13, h23], reverse=True)
    
    #
    # Shuffle the points into correct order.
    #
    if hs[0] is h12:
        if hs[1] is h13:
            p1, p2, p3 = p1, p2, p3
        elif hs[1] is h23:
            p1, p2, p3 = p2, p1, p3
    elif hs[0] is h13:
        if hs[1] is h12:
            p1, p2, p3 = p1, p3, p2
        elif hs[1] is h23:
            p1, p2, p3 = p3, p1, p2
    elif hs[0] is h23:
        if hs[1] is h12:
            p1, p2, p3 = p2, p3, p1
        elif hs[1] is h13:
            p1, p2, p3 = p3, p2, p1
    
    h, ratio, theta = _measure(p1, p2, p3)
    
    return p1, p2, p3, ratio, theta
Beispiel #2
0
def _measure(p1, p2, p3):
    """ Return hypotenuse, ratio and theta for a trio of ordered points.
    """
    ha, hb = _hypot(p3.x - p1.x, p3.y - p1.y), _hypot(p2.x - p1.x, p2.y - p1.y)
    va, vb = Vector(p1, p2), Vector(p1, p3)
    
    theta = _atan2(va.y, va.x)
    
    x = vb.x * _cos(-theta) - vb.y * _sin(-theta)
    y = vb.x * _sin(-theta) + vb.y * _cos(-theta)
    
    ratio = ha / hb
    theta = _atan2(y, x)
    
    return hb, ratio, theta
Beispiel #3
0
def rotate3d(
        point: Iterable[float], angle: float,
        axis: Iterable[float] = (0.0, 0.0, 1.0), rounding: int = -1,
        degrees: bool = True) -> Tuple[float]:
    """
    Rotate a point around an axis.

    Take a point in 3d space represented as a tuple or list of three
    (3) values and rotate it by an angle around a given axis vector.

    Parameters:
        point: The point to rotate. The format for the coordinates is ``(x, y, z)``.
        angle: The angle of rotation. By default, angle is set to be input in
            degrees. See the **degrees** parameter if you want to use radians instead.
        axis: The axis to rotate the point around. By default, this is the
            z-axis ``(0, 0, 1)``.
        rounding: The number of decimal points the result will be rounded to.
            Default value is -1, which does not round the end result.
        degrees: When set to ``True``, this function interprets the parameter
            **angle** as degrees. Set this parameter to ``False`` to use angles
            in radians. Default is ``True``.

    For the point and axis parameters, if only one value is given, the value
    will be assumed to be an x-coordinate with the y- and z-coordinates
    equal to zero (0). If two values are given, they will be assumed to
    be x- and y-coordinates with the z-coordinate equal to zero (0).
    """
    if len(point) <= 3 and len(axis) <= 3:
        p = Quaternion(0, *_makeListLen3(point))

        axis_i, axis_j, axis_k = _makeListLen3(axis)
        if _hypot(axis_i, axis_j, axis_k) == 0:
            raise ValueError(
                'The axis to rotate around must be a nonzero vector.')

        q = Quaternion.from_angle(angle*0.5, (axis_i, axis_j, axis_k), degrees=degrees)
        if abs(q) != 1.0:
            q = q.versor  # Ensures q is a unit vector.
        p_prime = q * p * q.inverse()
        if rounding != -1:
            p_prime = round(p_prime, rounding)

        i_prime, j_prime, k_prime = p_prime.get_vector_components()

        return (i_prime, j_prime, k_prime)

    else:
        if len(point) > 3:
            problem = "'point'"
        elif len(axis) > 3:
            problem = "'axis'"
        else:
            problem = "'point' and 'axis'"
        raise IndexError(
            f"{problem} must be a tuple or list of three (3) values.")
Beispiel #4
0
def hyp(x, y):
    return _hypot(x, y)
Beispiel #5
0
def hyp(x, y):
    return _hypot(x, y)
Beispiel #6
0
    def renderArea(self, width_, height_, srs, xmin_, ymin_, xmax_, ymax_, zoom):
        """
        """
        merc = Proj(srs)
        
        # use the center to figure out our UTM zone
        lon, lat = merc((xmin_ + xmax_)/2, (ymin_ + ymax_)/2, inverse=True)
        zone = lon2zone(lon)
        hemi = lat2hemi(lat)

        utm = Proj(proj='utm', zone=zone, datum='WGS84')
        
        # get to UTM coords
        (minlon, minlat), (maxlon, maxlat) = merc(xmin_, ymin_, inverse=1), merc(xmax_, ymax_, inverse=1)
        (xmin, ymin), (xmax, ymax) = utm(minlon, minlat), utm(maxlon, maxlat)

        # figure out how widely-spaced they should be
        pixels = _hypot(width_, height_)            # number of pixels across the image
        units = _hypot(xmax - xmin, ymax - ymin)    # number of UTM units across the image
        
        tick = self.tick * units/pixels             # desired tick length in UTM units
        
        count = pixels / self.spacing               # approximate number of lines across the image
        bound = units / count                       # too-precise step between lines in UTM units
        zeros = int(_ceil(_log(bound) / _log(10)))  # this value gets used again to format numbers
        step = int(_pow(10, zeros))                 # a step that falls right on the 10^n
        
        # and the outer UTM bounds
        xbot, xtop = int(xmin - xmin % step), int(xmax - xmax % step) + 2 * step
        ybot, ytop = int(ymin - ymin % step), int(ymax - xmax % step) + 2 * step
    
        # start doing things in pixels
        img = Image.new('RGBA', (width_, height_), (0xEE, 0xEE, 0xEE, 0x00))
        draw = ImageDraw.ImageDraw(img)
        xform = transform(width_, height_, xmin_, ymax_, xmax_, ymin_)
        
        lines = []
        labels = []
        
        for col in range(xbot, xtop, step):
            # set up the verticals
            utms = [(col, y) for y in range(ybot, ytop, step/10)]
            mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in utms]
            lines.append( [xform(x, y) for (x, y) in mercs] )
            
            # and the tick marks
            for row in range(ybot, ytop, step/10):
                mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in ((col, row), (col - tick, row))]
                lines.append( [xform(x, y) for (x, y) in mercs] )
        
        for row in range(ybot, ytop, step):
            # set up the horizontals
            utms = [(x, row) for x in range(xbot, xtop, step/10)]
            mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in utms]
            lines.append( [xform(x, y) for (x, y) in mercs] )
            
            # and the tick marks
            for col in range(xbot, xtop, step/10):
                mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in ((col, row), (col, row - tick))]
                lines.append( [xform(x, y) for (x, y) in mercs] )

        # set up the intersection labels
        for x in range(xbot, xtop, step):
            for y in range(ybot, ytop, step):
                lon, lat = utm(x, y, inverse=1)
                grid = lonlat2grid(lon, lat)
                point = xform(*merc(lon, lat))
                
                if self.display == 'utm':
                    e = ('%07d' % x)[:-zeros]
                    n = ('%07d' % y)[:-zeros]
                    text = ' '.join( [grid, e, n] )

                elif self.display == 'mgrs':
                    e, n = Proj(proj='utm', zone=lon2zone(lon), datum='WGS84')(lon, lat)
                    text = utm2mgrs(round(e), round(n), grid, zeros)
                
                labels.append( (point, text) )

        # do the drawing bits
        for ((x, y), text) in labels:
            x, y = x + 2, y - 18
            w, h = self.font.getsize(text)
            draw.rectangle((x - 2, y, x + w + 2, y + h), fill=(0xFF, 0xFF, 0xFF, 0x99))

        for line in lines:
            draw.line(line, fill=(0xFF, 0xFF, 0xFF))

        for line in lines:
            draw.line([(x-1, y-1) for (x, y) in line], fill=(0x00, 0x00, 0x00))

        for ((x, y), text) in labels:
            x, y = x + 2, y - 18
            draw.text((x, y), text, fill=(0x00, 0x00, 0x00), font=self.font)

        return img
Beispiel #7
0
    def renderArea(self, width_, height_, srs, xmin_, ymin_, xmax_, ymax_, zoom):
        """
        """
        merc = Proj(srs)
        
        # use the center to figure out our UTM zone
        lon, lat = merc((xmin_ + xmax_)/2, (ymin_ + ymax_)/2, inverse=True)
        zone = lon2zone(lon)
        hemi = lat2hemi(lat)

        utm = Proj(proj='utm', zone=zone, datum='WGS84')
        
        # get to UTM coords
        (minlon, minlat), (maxlon, maxlat) = merc(xmin_, ymin_, inverse=1), merc(xmax_, ymax_, inverse=1)
        (xmin, ymin), (xmax, ymax) = utm(minlon, minlat), utm(maxlon, maxlat)

        # figure out how widely-spaced they should be
        pixels = _hypot(width_, height_)            # number of pixels across the image
        units = _hypot(xmax - xmin, ymax - ymin)    # number of UTM units across the image
        
        tick = self.tick * units/pixels             # desired tick length in UTM units
        
        count = pixels / self.spacing               # approximate number of lines across the image
        bound = units / count                       # too-precise step between lines in UTM units
        zeros = int(_ceil(_log(bound) / _log(10)))  # this value gets used again to format numbers
        step = int(_pow(10, zeros))                 # a step that falls right on the 10^n
        
        # and the outer UTM bounds
        xbot, xtop = int(xmin - xmin % step), int(xmax - xmax % step) + 2 * step
        ybot, ytop = int(ymin - ymin % step), int(ymax - xmax % step) + 2 * step
    
        # start doing things in pixels
        img = Image.new('RGBA', (width_, height_), (0xEE, 0xEE, 0xEE, 0x00))
        draw = ImageDraw.ImageDraw(img)
        xform = transform(width_, height_, xmin_, ymax_, xmax_, ymin_)
        
        lines = []
        labels = []
        
        for col in range(xbot, xtop, step):
            # set up the verticals
            utms = [(col, y) for y in range(ybot, ytop, step/10)]
            mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in utms]
            lines.append( [xform(x, y) for (x, y) in mercs] )
            
            # and the tick marks
            for row in range(ybot, ytop, step/10):
                mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in ((col, row), (col - tick, row))]
                lines.append( [xform(x, y) for (x, y) in mercs] )
        
        for row in range(ybot, ytop, step):
            # set up the horizontals
            utms = [(x, row) for x in range(xbot, xtop, step/10)]
            mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in utms]
            lines.append( [xform(x, y) for (x, y) in mercs] )
            
            # and the tick marks
            for col in range(xbot, xtop, step/10):
                mercs = [merc(*utm(x, y, inverse=1)) for (x, y) in ((col, row), (col, row - tick))]
                lines.append( [xform(x, y) for (x, y) in mercs] )

        # set up the intersection labels
        for x in range(xbot, xtop, step):
            for y in range(ybot, ytop, step):
                lon, lat = utm(x, y, inverse=1)
                grid = lonlat2grid(lon, lat)
                point = xform(*merc(lon, lat))
                
                if self.display == 'utm':
                    e = ('%07d' % x)[:-zeros]
                    n = ('%07d' % y)[:-zeros]
                    text = ' '.join( [grid, e, n] )

                elif self.display == 'mgrs':
                    e, n = Proj(proj='utm', zone=lon2zone(lon), datum='WGS84')(lon, lat)
                    text = utm2mgrs(round(e), round(n), grid, zeros)
                
                labels.append( (point, text) )

        # do the drawing bits
        for ((x, y), text) in labels:
            x, y = x + 2, y - 18
            w, h = self.font.getsize(text)
            draw.rectangle((x - 2, y, x + w + 2, y + h), fill=(0xFF, 0xFF, 0xFF, 0x99))

        for line in lines:
            draw.line(line, fill=(0xFF, 0xFF, 0xFF))

        for line in lines:
            draw.line([(x-1, y-1) for (x, y) in line], fill=(0x00, 0x00, 0x00))

        for ((x, y), text) in labels:
            x, y = x + 2, y - 18
            draw.text((x, y), text, fill=(0x00, 0x00, 0x00), font=self.font)

        return img