예제 #1
0
파일: kad.py 프로젝트: orihikarna/Hermit
def calc_bezier_round_points(apos, avec, bpos, bvec, radius):
    _, alen, blen = vec2.find_intersection(apos, avec, bpos, bvec)
    debug = False
    if alen <= radius:
        print('BezierRound: alen < radius, {} < {}, at {}'.format(
            alen, radius, apos))
        debug = True
    if blen <= radius:
        print('BezierRound: blen < radius, {} < {}, at {}'.format(
            blen, radius, bpos))
        debug = True
    amid = vec2.scale(alen - radius, avec, apos)
    bmid = vec2.scale(blen - radius, bvec, bpos)
    #add_line( apos, amid, layer, width )
    #add_line( bpos, bmid, layer, width )
    angle = vec2.angle(avec, bvec)
    if angle < 0:
        #angle += 360
        angle *= -1
    ndivs = int(round(angle / 4.5))
    #print( 'BezierRound: angle = {}, ndivs = {}'.format( angle, ndivs ) )
    coeff = (math.sqrt(0.5) - 0.5) / 3 * 8
    #print( 'coeff = {}'.format( coeff ) )
    actrl = vec2.scale(alen + (coeff - 1) * radius, avec, apos)
    bctrl = vec2.scale(blen + (coeff - 1) * radius, bvec, bpos)
    pnts = [amid, actrl, bctrl, bmid]
    curv = [apos]
    for pos in calc_bezier_points(pnts, ndivs, debug):
        curv.append(pos)
    curv.append(bpos)
    return curv
예제 #2
0
파일: kad.py 프로젝트: orihikarna/Hermit
def calc_spline_points(apos, avec, bpos, bvec, num_divs, vec_scale):
    curv = [apos]
    for i in range(1, num_divs):
        t = float(i) / num_divs
        pos = vec2.add(vec2.scale(h0(t), apos), vec2.scale(h1(t), bpos))
        vec = vec2.add(vec2.scale(g0(t), (avec[1], -avec[0])),
                       vec2.scale(g1(t), (bvec[1], -bvec[0])))
        pos = vec2.scale(vec_scale, vec, pos)
        curv.append(pos)
    curv.append(bpos)
    return curv
예제 #3
0
파일: kad.py 프로젝트: orihikarna/Hermit
def add_wire_offsets_straight(prms_a, prms_b, net, layer, width, radius):
    pos_a, offsets_a = prms_a
    pos_b, offsets_b = prms_b
    pnts_a = [pos_a]
    pnts_b = [pos_b]
    for off_len_a, off_angle_a in offsets_a:
        pos_a = vec2.scale(off_len_a, vec2.rotate(-off_angle_a), pos_a)
        pnts_a.append(pos_a)
    for off_len_b, off_angle_b in offsets_b:
        pos_b = vec2.scale(off_len_b, vec2.rotate(-off_angle_b), pos_b)
        pnts_b.append(pos_b)
    pnts = pnts_a
    for pnt_b in reversed(pnts_b):
        pnts.append(pnt_b)
    add_wire_straight(pnts, net, layer, width, radius)
예제 #4
0
파일: kad.py 프로젝트: orihikarna/Hermit
def calc_bezier_corner_points(apos, avec, bpos, bvec, pitch=1, ratio=0.7):
    _, alen, blen = vec2.find_intersection(apos, avec, bpos, bvec)
    debug = False
    if alen <= 0:
        print('BezierCorner: alen = {} < 0, at {}'.format(alen, apos))
        debug = True
    if blen <= 0:
        print('BezierCorner: blen = {} < 0, at {}'.format(blen, bpos))
        debug = True
    # if debug:
    #     return []
    actrl = vec2.scale(alen * ratio, avec, apos)
    bctrl = vec2.scale(blen * ratio, bvec, bpos)
    ndivs = int(round((alen + blen) / pitch))
    pnts = [apos, actrl, bctrl, bpos]
    curv = calc_bezier_points(pnts, ndivs, debug)
    return curv
예제 #5
0
파일: kad.py 프로젝트: orihikarna/Hermit
def calc_bezier_points(pnts, num_divs, debug=False):
    num_pnts = len(pnts)
    tmp = [(0, 0) for n in range(num_pnts)]
    curv = [pnts[0]]
    for i in range(1, num_divs):
        t = float(i) / num_divs
        s = 1 - t
        for n in range(num_pnts):
            tmp[n] = pnts[n]
        for L in range(num_pnts - 1, 0, -1):
            for n in range(L):
                tmp[n] = vec2.scale(s, tmp[n], vec2.scale(t, tmp[n + 1]))
        curv.append(tmp[0])
    curv.append(pnts[-1])
    #add_lines( curv, layer, width )
    if debug:  # debug
        for pnt in pnts:
            add_arc(pnt, vec2.add(pnt, (20, 0)), 360, 'F.Fab', 4)
    return curv
예제 #6
0
파일: kad.py 프로젝트: orihikarna/Hermit
def add_wire_offsets_directed(prms_a, prms_b, net, layer, width, radius):
    pos_a, offsets_a, angle_a = prms_a
    pos_b, offsets_b, angle_b = prms_b
    pnts_a = [pos_a]
    pnts_b = [pos_b]
    for off_len_a, off_angle_a in offsets_a:
        pos_a = vec2.scale(off_len_a, vec2.rotate(-off_angle_a), pos_a)
        pnts_a.append(pos_a)
    for off_len_b, off_angle_b in offsets_b:
        pos_b = vec2.scale(off_len_b, vec2.rotate(-off_angle_b), pos_b)
        pnts_b.append(pos_b)
    apos = pnts_a[-1]
    bpos = pnts_b[-1]
    dir_a = vec2.rotate(-angle_a)
    dir_b = vec2.rotate(-angle_b)
    xpos, _, _ = vec2.find_intersection(apos, dir_a, bpos, dir_b)
    pnts = pnts_a
    pnts.append(xpos)
    for pnt_b in reversed(pnts_b):
        pnts.append(pnt_b)
    add_wire_straight(pnts, net, layer, width, radius)
예제 #7
0
파일: kad.py 프로젝트: orihikarna/Hermit
def add_wire_straight(pnts, net, layer, width, radius=0):
    rpnts = []
    for idx, curr in enumerate(pnts):
        if idx == 0 or idx + 1 == len(pnts):  # first or last
            rpnts.append(curr)
            continue
        prev = pnts[idx - 1]
        next = pnts[idx + 1]
        vec_a = vec2.sub(prev, curr)
        vec_b = vec2.sub(next, curr)
        len_a = vec2.length(vec_a)
        len_b = vec2.length(vec_b)
        length = min(abs(radius), len_a / 2 if idx - 1 > 0 else len_a,
                     len_b / 2 if idx + 1 < len(pnts) - 1 else len_b)
        if length < 10**(-PointDigits):
            rpnts.append(curr)
        else:
            if radius < 0:  # and abs( vec2.dot( vec_a, vec_b ) ) < len_a * len_b * 0.001:
                # bezier circle
                num_divs = 15
                cef = (math.sqrt(0.5) - 0.5) / 3 * 8
                bpnts = []
                bpnts.append(vec2.scale(length / len_a, vec_a, curr))
                bpnts.append(vec2.scale(length / len_a * cef, vec_a, curr))
                bpnts.append(vec2.scale(length / len_b * cef, vec_b, curr))
                bpnts.append(vec2.scale(length / len_b, vec_b, curr))
                num_pnts = len(bpnts)
                tmp = [(0, 0) for n in range(num_pnts)]
                rpnts.append(bpnts[0])
                for i in range(1, num_divs):
                    t = float(i) / num_divs
                    s = 1 - t
                    for n in range(num_pnts):
                        tmp[n] = bpnts[n]
                    for L in range(num_pnts - 1, 0, -1):
                        for n in range(L):
                            tmp[n] = vec2.scale(s, tmp[n],
                                                vec2.scale(t, tmp[n + 1]))
                    rpnts.append(tmp[0])
                rpnts.append(bpnts[-1])
            else:
                rpnts.append(vec2.scale(length / len_a, vec_a, curr))
                rpnts.append(vec2.scale(length / len_b, vec_b, curr))
    for idx, curr in enumerate(rpnts):
        if idx == 0:
            continue
        prev = rpnts[idx - 1]
        if vec2.distance(prev, curr) > 0.01:
            add_track(prev, curr, net, layer, width)
예제 #8
0
파일: kad.py 프로젝트: orihikarna/Hermit
def add_wire_zigzag(pos_a, pos_b, angle, delta_angle, net, layer, width,
                    radius):
    mid_pos = vec2.scale(0.5, vec2.add(pos_a, pos_b))
    dir = vec2.rotate(-angle)
    mid_dir1 = vec2.rotate(-angle + delta_angle)
    mid_dir2 = vec2.rotate(-angle - delta_angle)
    _, ka1, _ = vec2.find_intersection(pos_a, dir, mid_pos, mid_dir1)
    _, ka2, _ = vec2.find_intersection(pos_a, dir, mid_pos, mid_dir2)
    mid_angle = (angle - delta_angle) if abs(ka1) < abs(ka2) else (angle +
                                                                   delta_angle)
    add_wire_directed((pos_a, angle), (mid_pos, mid_angle), net, layer, width,
                      radius)
    add_wire_directed((pos_b, angle), (mid_pos, mid_angle), net, layer, width,
                      radius)
예제 #9
0
파일: kad.py 프로젝트: orihikarna/Hermit
def drawRect(pnts, layer, R=75, width=2):
    if R > 0:
        arcs = []
        for idx, a in enumerate(pnts):
            b = pnts[idx - 1]
            vec = vec2.sub(b, a)
            length = vec2.length(vec)
            delta = vec2.scale(R / length, vec)
            na = vec2.add(a, delta)
            nb = vec2.sub(b, delta)
            ctr = vec2.add(nb, (delta[1], -delta[0]))
            arcs.append((ctr, na, nb))
            add_line(na, nb, layer, width)
        for idx, (ctr, na, nb) in enumerate(arcs):
            arc = add_arc2(ctr, nb, arcs[idx - 1][1], -90, layer, width)
            # print( "na   ", pnt.mils2unit( vec2.round( na ) ) )
            # print( "start", arc.GetArcStart() )
            # print( "nb   ", pnt.mils2unit( vec2.round( nb ) ) )
            # print( "end  ", arc.GetArcEnd() )
    else:
        for idx, a in enumerate(pnts):
            b = pnts[idx - 1]
            add_line(a, b, layer, width)
예제 #10
0
파일: kad.py 프로젝트: orihikarna/Hermit
def draw_corner(cnr_type, a, cnr_data, b, layer, width, dump=False):
    apos, aangle = a
    bpos, bangle = b
    avec = vec2.rotate(aangle)
    bvec = vec2.rotate(bangle + 180)
    curv = None
    if cnr_type != Bezier and abs(vec2.dot(avec, bvec)) > 0.999:
        cnr_type = Line
        #print( avec, bvec )
    if cnr_type == Line:
        add_line(apos, bpos, layer, width)
    elif cnr_type == Linear:
        xpos, alen, blen = vec2.find_intersection(apos, avec, bpos, bvec)
        if cnr_data == None:
            add_line(apos, xpos, layer, width)
            add_line(bpos, xpos, layer, width)
        else:
            delta = cnr_data[0]
            #print( delta, alen, xpos )
            amid = vec2.scale(alen - delta, avec, apos)
            bmid = vec2.scale(blen - delta, bvec, bpos)
            add_line(apos, amid, layer, width)
            add_line(bpos, bmid, layer, width)
            add_line(amid, bmid, layer, width)
    elif cnr_type == Bezier:
        num_data = len(cnr_data)
        alen = cnr_data[0]
        blen = cnr_data[-2]
        ndivs = cnr_data[-1]
        apos2 = vec2.scale(alen, avec, apos)
        bpos2 = vec2.scale(blen, bvec, bpos)
        pnts = [apos, apos2]
        if num_data > 3:
            for pt in cnr_data[1:num_data - 2]:
                pnts.append(pt)
        pnts.append(bpos2)
        pnts.append(bpos)
        curv = calc_bezier_points(pnts, ndivs)
        add_lines(curv, layer, width)
    elif cnr_type == BezierRound:
        radius = cnr_data[0]
        # _, alen, blen = vec2.find_intersection( apos, avec, bpos, bvec )
        # debug = False
        # if alen <= radius:
        #     print( 'BezierRound: alen < radius, {} < {}, at {}'.format( alen, radius, apos ) )
        #     debug = True
        # if blen <= radius:
        #     print( 'BezierRound: alen < radius, {} < {}, at {}'.format( blen, radius, bpos ) )
        #     debug = True
        # amid = vec2.scale( alen - radius, avec, apos )
        # bmid = vec2.scale( blen - radius, bvec, bpos )
        # add_line( apos, amid, layer, width )
        # add_line( bpos, bmid, layer, width )
        # angle = vec2.angle( avec, bvec )
        # if angle < 0:
        #     #angle += 360
        #     angle *= -1
        # ndivs = int( round( angle / 4.5 ) )
        # #print( 'BezierRound: angle = {}, ndivs = {}'.format( angle, ndivs ) )
        # coeff = (math.sqrt( 0.5 ) - 0.5) / 3 * 8
        # #print( 'coeff = {}'.format( coeff ) )
        # actrl = vec2.scale( alen + (coeff - 1) * radius, avec, apos )
        # bctrl = vec2.scale( blen + (coeff - 1) * radius, bvec, bpos )
        # pnts = [amid, actrl, bctrl, bmid]
        curv = calc_bezier_round_points(apos, avec, bpos, bvec, radius)
        add_lines(curv, layer, width)
    elif cnr_type == Round:
        radius = cnr_data[0]
        # print( 'Round: radius = {}'.format( radius ) )
        # print( apos, avec, bpos, bvec )
        xpos, alen, blen = vec2.find_intersection(apos, avec, bpos, bvec)
        # print( xpos, alen, blen )
        debug = False
        if not is_supported_round_angle(aangle):
            pass
            #print( 'Round: warning aangle = {}'.format( aangle ) )
            #debug = True
        if not is_supported_round_angle(bangle):
            pass
            #print( 'Round: warning bangle = {}'.format( bangle ) )
            #debug = True
        if alen < radius:
            print('Round: alen < radius, {} < {}'.format(alen, radius))
            debug = True
        if blen < radius:
            print('Round: blen < radius, {} < {}'.format(blen, radius))
            debug = True
        if debug:
            add_arc(xpos, vec2.add(xpos, (10, 0)), 360, layer, width)
            return b, curv
        angle = vec2.angle(avec, bvec)
        angle = math.ceil(angle * 10) / 10
        tangent = math.tan(abs(angle) / 2 / 180 * math.pi)
        side_len = radius / tangent
        # print( 'angle = {}, radius = {}, side_len = {}, tangent = {}'.format( angle, radius, side_len, tangent ) )

        amid = vec2.scale(-side_len, avec, xpos)
        bmid = vec2.scale(-side_len, bvec, xpos)
        add_line(apos, amid, layer, width)
        add_line(bpos, bmid, layer, width)

        aperp = (-avec[1], avec[0])
        if angle >= 0:
            ctr = vec2.scale(-radius, aperp, amid)
            add_arc2(ctr, bmid, amid, 180 - angle, layer, width)
        else:
            ctr = vec2.scale(+radius, aperp, amid)
            add_arc2(ctr, amid, bmid, 180 + angle, layer, width)
    elif cnr_type == Spline:
        vec_scale = cnr_data[0]
        ndivs = int(round(vec2.distance(apos, bpos) / 2.0))
        avec = vec2.rotate(aangle + 90)
        bvec = vec2.rotate(bangle - 90)
        curv = calc_spline_points(apos, avec, bpos, bvec, ndivs, vec_scale)
        add_lines(curv, layer, width)
    return b, curv