#let phone( width: 200pt, height: 400pt, stroke: 3pt+black, body: [], ) = { let h_screen = height*12/15 let w_screen = width*8/10 let r = (height/15) let h_button = (height - h_screen) / 6 let w_button = w_screen / 3 let dy_button = -((height - h_screen) / 2 - h_button) / 2 let h-top-line = ((height - h_screen) / 2) / 6 let w-top-line-bar = w_screen / 2 let dy-top-line = (((height - h_screen) / 2) - h-top-line) / 3 let r-cam = ((height - h_screen) / 2) / 5 let dx-cam = -r-cam*2 let dy-cam = ((height - h_screen) / 2 / 2) - r-cam let top-line = stack( dir: ltr, circle(radius: h-top-line/2, stroke: stroke), h(h-top-line), rect( width: w-top-line-bar, height: h-top-line, radius: h-top-line/2, stroke: stroke, ), h(h-top-line), circle(radius: h-top-line/2, stroke: stroke), h(h-top-line), circle(radius: h-top-line/2, stroke: stroke) ) rect( width: width, height: height, inset: 0pt, stroke: stroke, radius: r, { place(center+horizon, rect( width: w_screen, height: h_screen, stroke: stroke, body, ) ) place(center+bottom, dy: dy_button, rect( width: w_button, height: h_button, stroke: stroke, radius: h_screen / 2, ) ) place(center+top, dy: dy-top-line, top-line ) place(right+top, dx: dx-cam, dy: dy-cam, circle(radius: r-cam, stroke: stroke) ) } ) } #let polar( x0: 0pt, y0: 0pt, r: 0pt, th: 0deg, ) = { ( x0 + r * calc.cos(th), y0 + r * calc.sin(th), ) } #let gear( //x0: 0pt, y0: 0pt, out-rad: 100pt, in-rad: none, center-rad: none, nb-teeth: 6, teeth-angle: none, stroke: black + 3pt, fill: luma(70%), ) = { let x0 = out-rad let y0 = out-rad let teeth-angle = if teeth-angle == none { 360deg / nb-teeth / 2 } else { teeth-angle } let inter-teeth-angle = (360deg / nb-teeth) - teeth-angle let in-rad = if in-rad == none { out-rad * 0.75 } else { in-rad } let center-rad = if center-rad == none { in-rad / 2 } else { center-rad } box(width: 2*out-rad, height: 2*out-rad, { //place(left+bottom, line(start: (0%, -50%), end: (100%, -50%))) //place(left+bottom, line(start: (50%, 0%), end: (50%, -100%))) curve( stroke: stroke, fill: fill, fill-rule: "even-odd", ..for i in range(nb-teeth) { let angle = i * 360deg / nb-teeth let center_off = calc.sin(teeth-angle/2) * in-rad let (x0_1, y0_1) = polar(x0: x0, y0: y0, r: center_off, th: angle - 90deg) let (x0_2, y0_2) = polar(x0: x0, y0: y0, r: center_off, th: angle + 90deg) let p0 = polar(x0: x0_1, y0: y0_1, r: out-rad, th: angle) let p1 = polar(x0: x0_2, y0: y0_2, r: out-rad, th: angle) let p2 = polar(x0: x0, y0: y0, r: in-rad, th: angle + inter-teeth-angle/2) let p3 = polar(x0: x0, y0: y0, r: in-rad, th: angle + 3*inter-teeth-angle/2) let u2 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + inter-teeth-angle/2 + 90deg) let u3 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + 3*inter-teeth-angle/2 + 90deg) let l2 = 4 * in-rad / 3 * calc.tan(inter-teeth-angle / 4) / 1pt let l3 = -l2 //let l2 = 1 let q2 = (p2.at(0) + l2 * u2.at(0), p2.at(1) + l2 * u2.at(1)) let q3 = (p3.at(0) + l3 * u3.at(0), p3.at(1) + l3 * u3.at(1)) let result = ( curve.line(p0), curve.line(p1), curve.line(p2), /* curve.line(q2), curve.line(p2), curve.line(p3), curve.line(q3), curve.line(p3), */ curve.cubic(q2, q3, p3) ) if i == 0 { result.insert(0, curve.move(p0)) } result }, curve.close(mode: "straight"), ..for i in range(4) { let angle = i * 360deg / 4 let p0 = polar(x0: x0, y0: y0, r: center-rad, th: angle) let u0 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + 90deg) let p1 = polar(x0: x0, y0: y0, r: center-rad, th: angle+90deg) let u1 = polar(x0: 0pt, y0: 0pt, r: 1pt, th: angle + 180deg) let l0 = 4 * center-rad / 3 * calc.tan(90deg / 4) / 1pt let l1 = -l0 let q0 = (p0.at(0) + l0 * u0.at(0), p0.at(1) + l0 * u0.at(1)) let q1 = (p1.at(0) + l1 * u1.at(0), p1.at(1) + l1 * u1.at(1)) let result = ( curve.cubic(q0, q1, p1), ) if i == 0 { result.insert(0, curve.move(p0)) } result }, curve.close() ) /*place(left+bottom, // wtf? dx: out-rad - center-rad, dy: -out-rad + center-rad, circle( radius: center-rad, stroke: stroke, fill: fill-center, ) )*/ }) } #let wrench(height: 200pt) = rotate(45deg, image("imgs/ico/wrench.svg", height: height)) #let apk(height: 100pt) = image("imgs/ico/apk.svg", height: height) #let apks(height: 100pt) = { place(apk(height: height)) place(dx: height * 4 / 10, dy: -height * 3 / 10, apk(height: height)) place(dx: height * 6 / 10, dy: height / 10, apk(height: height)) } #let transfo(height: 200pt) = { box(width: height, height: height, { place( left+bottom, dx: height / 12, dy: - height * 3 / 12, gear(out-rad: height/3) ) place( left+bottom, dx: height * 2 / 5, dy: 0pt, wrench(height: height*7/8) ) }) } #let loop(height: 100pt) = image("imgs/ico/loop.svg", height: height) #let analyse(height: 200pt) = { box(width: height, stroke: black, { apk(height: height) place( left+top, dx: - height * 3/10, dy: - height * 1 / 10, loop(height: height/2) ) }) } #let report(height: 100pt) = image("imgs/ico/report.svg", height: height) #let th-outline(height: 600pt, width: 900pt, hide-static: false) = { let small-ico-h = height / 16 let big-ico-h = height / 6 let static = stack(dir: ltr, apks(height: small-ico-h), h(big-ico-h), $ -> $, h(big-ico-h), analyse(height: big-ico-h), h(big-ico-h), $ -> $, h(big-ico-h), report(height: small-ico-h), ) let th = stack(dir: ltr, apks(height: small-ico-h), h(big-ico-h*2/3), $->$, h(big-ico-h/4), phone(height: height/4, width: height/8), h(big-ico-h/4), $->$, h(big-ico-h/4), transfo(height: big-ico-h), h(big-ico-h/4), $->$, h(big-ico-h/4), apk(height: small-ico-h), h(big-ico-h/4), $->$, h(big-ico-h/4), analyse(height: big-ico-h), h(big-ico-h/4), $->$, h(big-ico-h/4), report(height: small-ico-h), ) box(height: 600pt, width: 900pt, stack( if hide-static { hide(static)} else { static }, v(big-ico-h), th, ) ) } #gear() /* #phone(body: [Hello World!]) #wrench() #apk() #v(4em) #apks() #v(12em) #transfo() #analyse() #report() */