Angel wings

Zhukovsky airfoil shapes via Joukowsky transform

Log in to post a comment.

Canvas.setpenopacity(-0.5);

const t = new Turtle();

function airfoil(cx, cy, n) {
    const i = []
    const j = []

    let r = Math.sqrt((cx - 1)**2 + cy**2)
    let dphi = 2 * Math.PI / n

    for (let k = 0, phi = -Math.PI; k <= n; k++, phi += dphi) {
        let x = cx + r * Math.cos(phi)
        let y = cy + r * Math.sin(phi)
        
        i[k] = x * (1 + 1 / (x**2 + y**2))
        j[k] = y * (1 - 1 / (x**2 + y**2))
    }
    
    return [i, j]
}

function draw_airfoil(i, j, Rw, phi, Rc, flip) {
    let i_min = Math.min(...i)
    
    let x0 = (i[0] - i_min) * Rw
    let y0 = j[0] * Rw
    
    let sx0 = Rc * Math.cos(phi)
    let sy0 = Rc * Math.sin(phi)
    
    t.jump(sx0, sy0)
    
    for (let ind = 0; ind < i.length; ind++) {
        let x = (i[ind] - i_min) * Rw;
        let y = j[ind] * Rw;
        
        if (flip) {
            [x, y] = [x * Math.cos(phi) + y * Math.sin(phi), -x * Math.sin(phi) + y * Math.cos(phi)]
            
            t.goto(sx0 + x, sy0 - y)
        }
        else {
            [x, y] = [x * Math.cos(phi) - y * Math.sin(phi), x * Math.sin(phi) + y * Math.cos(phi)]
            
            t.goto(sx0 + x, sy0 + y)
        }
    }
}

const Rw = 15
const Rc = 16

// eye

t.jump(-Rc, 0)
t.seth(-90)
t.circle(Rc)

t.jump(-Rc, 0)
t.seth(-45)
t.circle(Rc * Math.sqrt(2), 90)

t.jump(-Rc, 0)
t.seth(-60)
t.circle(Rc * 2 /  Math.sqrt(3), 120)

t.jump(Rc, 0)
t.seth(135)
t.circle(Rc * Math.sqrt(2), 90)

t.jump(Rc, 0)
t.seth(120)
t.circle(Rc * 2 /  Math.sqrt(3), 120)

for (let r = 3; r <= 6; r += 0.25) {
    t.jump(-r, 0)
    t.seth(-90)
    t.circle(r)
}

// wings

const N1 = 20

for (let k = 0; k < N1; k++) {
    let ci = -0.15;
    let cj = -0.1 - 0.45 * k / (N1 - 1);
    
    [i, j] = airfoil(ci, cj, 100)
    
    let phi1 = -Math.PI * (-0.1 + 0.2 * (1 - k / (N1 - 1))) 
    let phi2 = -Math.PI - phi1

    draw_airfoil(i, j, Rw, phi1, Rc, false)
    draw_airfoil(i, j, Rw, phi2, Rc, true)
}

const N2 = 20
const Rw2 = Rw * 0.8

for (let k = 0; k < N2; k++) {
    let ci = -0.15;
    let cj = -0.2 - 0.65 * k / (N2 - 1);
    
    [i, j] = airfoil(ci, cj, 100)
    
    let phi1 = Math.PI * (0.2 + 0.25 * k / (N2 - 1)) 
    let phi2 = -Math.PI - phi1

    draw_airfoil(i, j, Rw2, phi1, Rc, false)
    draw_airfoil(i, j, Rw2, phi2, Rc, true)
}

const N3 = 20
const Rw3 = Rw * 1.2

for (let k = 0; k < N3; k++) {
    let ci = -0.15;
    let cj = -0.1 - 0.15 * (1 - k / (N3 - 1));
    
    [i, j] = airfoil(ci, cj, 100)
    
    let phi1 = -Math.PI * (0.3 + 0.15 * (1 - k / (N3 - 1))) 
    let phi2 = -Math.PI - phi1

    draw_airfoil(i, j, Rw3, phi1, Rc, true)
    draw_airfoil(i, j, Rw3, phi2, Rc, false)
}