예제 #1
0
 def _xy(s):
     if th == 0:
         return Coord2(0.0, 0.0)
     elif s <= Ltot / 2:
         (fsin, fcos) = fresnel(s / (sq2pi * a))
         X = sq2pi * a * fcos
         Y = sq2pi * a * fsin
     else:
         (fsin, fcos) = fresnel((Ltot - s) / (sq2pi * a))
         X = (
             sq2pi
             * a
             * (
                 facos
                 + np.cos(2 * th) * (facos - fcos)
                 + np.sin(2 * th) * (fasin - fsin)
             )
         )
         Y = (
             sq2pi
             * a
             * (
                 fasin
                 - np.cos(2 * th) * (fasin - fsin)
                 + np.sin(2 * th) * (facos - fcos)
             )
         )
     return Coord2(X, Y)
예제 #2
0
def euler_end_pt(
        start_point=(0.0, 0.0), radius=10.0, input_angle=0.0,
        angle_amount=90.0):
    """Gives the end point of a simple Euler bend as a Coord2"""

    th = abs(angle_amount) * DEG2RAD / 2.0
    R = radius
    clockwise = bool(angle_amount < 0)

    (fsin, fcos) = fresnel(sqrt(2 * th / pi))

    a = 2 * sqrt(2 * pi * th) * (np.cos(th) * fcos + np.sin(th) * fsin)
    r = a * R
    X = r * np.cos(th)
    Y = r * np.sin(th)

    if clockwise:
        Y *= -1

    pt = Coord2(X, Y) + start_point
    pt.rotate(rotation_center=start_point, rotation=input_angle)
    return pt
예제 #3
0
def euler_bend_points(
    angle_amount: float = 90.0,
    radius: float = 10.0,
    resolution: float = 150.0,
    use_cache: bool = True,
) -> List[Coord2]:
    """ Base euler bend, no transformation, emerging from the origin."""
    # Check if we've calculated this already
    key = (angle_amount, radius, resolution)
    if key in __euler_bend_cache__ and use_cache:
        return __euler_bend_cache__[key]

    if angle_amount < 0:
        raise ValueError(
            "angle_amount should be positive. Got {}".format(angle_amount))
    # End angle
    eth = angle_amount * DEG2RAD

    # If bend is trivial, return a trivial shape
    if eth == 0.0:
        return [Coord2(0, 0)]

    # Curve min radius
    R = radius

    # Total displaced angle
    th = eth / 2.0

    # Total length of curve
    Ltot = 4 * R * th

    # Compute curve ##
    a = sqrt(R**2.0 * np.abs(th))
    sq2pi = sqrt(2.0 * pi)

    # Function for computing curve coords
    (fasin, facos) = fresnel(sqrt(2.0 / pi) * R * th / a)

    def _xy(s):
        if th == 0:
            return Coord2(0.0, 0.0)
        elif s <= Ltot / 2:
            (fsin, fcos) = fresnel(s / (sq2pi * a))
            X = sq2pi * a * fcos
            Y = sq2pi * a * fsin
        else:
            (fsin, fcos) = fresnel((Ltot - s) / (sq2pi * a))
            X = (sq2pi * a *
                 (facos + np.cos(2 * th) * (facos - fcos) + np.sin(2 * th) *
                  (fasin - fsin)))
            Y = (sq2pi * a *
                 (fasin - np.cos(2 * th) * (fasin - fsin) + np.sin(2 * th) *
                  (facos - fcos)))
        return Coord2(X, Y)

    # Parametric step size
    step = Ltot / int(th * resolution)

    # Generate points
    points = []
    for i in range(0, int(round(Ltot / step)) + 1):
        points += [_xy(i * step)]

    # Cache calculated points
    if use_cache:
        __euler_bend_cache__[(angle_amount, radius, resolution)] = points

    return points