{"id":45387,"date":"2026-04-02T21:52:41","date_gmt":"2026-04-02T13:52:41","guid":{"rendered":"https:\/\/www.qiusir.com\/?p=45387"},"modified":"2026-04-03T10:04:40","modified_gmt":"2026-04-03T02:04:40","slug":"qiutopia%e6%8a%9b%e4%bd%93%e8%bf%90%e5%8a%a8%e8%a7%a3%e6%9e%90","status":"publish","type":"post","link":"https:\/\/www.qiusir.com\/?p=45387","title":{"rendered":"qiutopIA\u629b\u4f53\u8fd0\u52a8\u89e3\u6790"},"content":{"rendered":"\n<div id=\"qiusir-projectile-bold-family-final\" style=\"max-width: 850px; margin: 10px auto; background: #ffffff; color: #334155; border-radius: 12px; border: 1px solid #e2e8f0; overflow: hidden; font-family: -apple-system, sans-serif;\">\n\n    <svg id=\"canvas-bold\" width=\"100%\" height=\"560\" viewBox=\"0 0 800 560\" style=\"display: block; background: #ffffff; touch-action: none;\">\n        <defs>\n            <marker id=\"vb-arr-v0\" markerWidth=\"3\" markerHeight=\"3\" refX=\"2\" refY=\"1.5\" orient=\"auto\"><path d=\"M0,0 L3,1.5 L0,3\" fill=\"#ef4444\" \/><\/marker>\n            <marker id=\"vb-arr-vt\" markerWidth=\"3\" markerHeight=\"3\" refX=\"2\" refY=\"1.5\" orient=\"auto\"><path d=\"M0,0 L3,1.5 L0,3\" fill=\"#3b82f6\" \/><\/marker>\n            <marker id=\"vb-arr-dv\" markerWidth=\"3\" markerHeight=\"3\" refX=\"2\" refY=\"1.5\" orient=\"auto\"><path d=\"M0,0 L3,1.5 L0,3\" fill=\"#10b981\" \/><\/marker>\n            <marker id=\"vb-arr-sum\" markerWidth=\"3\" markerHeight=\"3\" refX=\"2\" refY=\"1.5\" orient=\"auto\"><path d=\"M0,0 L3,1.5 L0,3\" fill=\"#f59e0b\" \/><\/marker>\n            <marker id=\"vb-arr-s\" markerWidth=\"4\" markerHeight=\"4\" refX=\"3\" refY=\"2\" orient=\"auto\"><path d=\"M0,0 L4,2 L0,4\" fill=\"#8b5cf6\" \/><\/marker>\n        <\/defs>\n\n        <line x1=\"0\" y1=\"500\" x2=\"800\" y2=\"500\" stroke=\"#f1f5f9\" stroke-width=\"4\" \/>\n        \n        <g id=\"vb-family-layer\"><\/g>\n        \n        <path id=\"vb-best-trace\" d=\"\" stroke=\"#facc15\" stroke-width=\"3.5\" fill=\"none\" opacity=\"0.4\" stroke-dasharray=\"8,4\" \/>\n        <circle id=\"vb-best-land\" r=\"5\" fill=\"#facc15\" stroke=\"#ca8a04\" stroke-width=\"1.5\" opacity=\"0\" \/>\n        \n        <path id=\"vb-full-trace-bg\" d=\"\" stroke=\"#94a3b8\" stroke-width=\"3\" fill=\"none\" opacity=\"0.2\" stroke-dasharray=\"6,4\"\/>\n        \n        <g id=\"vb-static-analysis\"><\/g>\n\n        <rect id=\"vb-plat\" x=\"0\" y=\"100\" width=\"40\" height=\"400\" fill=\"#f8fafc\" stroke=\"#cbd5e1\" \/>\n        <circle id=\"vb-origin-dot\" cx=\"40\" cy=\"100\" r=\"6\" fill=\"none\" stroke=\"#2563eb\" stroke-width=\"2\" \/>\n        <line id=\"vb-vec-v0-fixed\" stroke=\"#ef4444\" stroke-width=\"2.5\" marker-end=\"url(#vb-arr-v0)\" \/>\n\n        <g id=\"vb-realtime-layer\">\n            <path id=\"vb-active-trace\" d=\"\" stroke=\"#2563eb\" stroke-width=\"7\" fill=\"none\" stroke-linecap=\"round\" \/>\n            \n            <line id=\"vb-dyn-aux-1\" stroke=\"#94a3b8\" stroke-width=\"1.2\" stroke-dasharray=\"3,2\" \/>\n            <line id=\"vb-dyn-aux-2\" stroke=\"#94a3b8\" stroke-width=\"1.2\" stroke-dasharray=\"3,2\" \/>\n\n            <line id=\"vb-dyn-v0\" stroke=\"#ef4444\" stroke-width=\"2.5\" marker-end=\"url(#vb-arr-v0)\" \/>\n            <line id=\"vb-dyn-vt\" stroke=\"#3b82f6\" stroke-width=\"2.5\" marker-end=\"url(#vb-arr-vt)\" \/>\n            <line id=\"vb-dyn-dv\" stroke=\"#10b981\" stroke-width=\"3\" marker-end=\"url(#vb-arr-dv)\" \/>\n            <line id=\"vb-dyn-sum\" stroke=\"#f59e0b\" stroke-width=\"3\" marker-end=\"url(#vb-arr-sum)\" \/>\n            \n            <line id=\"vb-vec-s\" x1=\"40\" y1=\"100\" x2=\"40\" y2=\"100\" stroke=\"#8b5cf6\" stroke-width=\"3\" marker-end=\"url(#vb-arr-s)\" \/>\n            <circle id=\"vb-ball\" r=\"11\" fill=\"#2563eb\" stroke=\"#ffffff\" stroke-width=\"2.5\" \/>\n        <\/g>\n    <\/svg>\n\n    <div style=\"background: #f8fafc; padding: 15px 20px; border-top: 1px solid #f1f5f9;\">\n        <div style=\"display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 10px;\">\n            <div style=\"display: flex; align-items: center; gap: 8px;\"><span style=\"font-size: 11px; width: 60px; font-weight:700;\">\u9ad8\u5ea6 H<\/span><input type=\"range\" id=\"vb-h\" min=\"0\" max=\"400\" value=\"400\" style=\"flex:1\"><\/div>\n            <div style=\"display: flex; align-items: center; gap: 8px;\"><span style=\"font-size: 11px; width: 60px; font-weight:700;\">\u521d\u901f V\u2080<\/span><input type=\"range\" id=\"vb-v\" min=\"50\" max=\"420\" value=\"240\" style=\"flex:1\"><\/div>\n            <div style=\"display: flex; align-items: center; gap: 8px;\"><span style=\"font-size: 11px; width: 60px; font-weight:700;\">\u89d2\u5ea6 \u03b8<\/span><input type=\"range\" id=\"vb-a\" min=\"-90\" max=\"90\" value=\"30\" style=\"flex:1\"><\/div>\n            <div style=\"display: flex; align-items: center; gap: 8px;\"><span style=\"font-size: 11px; width: 60px; font-weight:700;\">\u65f6\u95f4 T<\/span><input type=\"range\" id=\"vb-t\" min=\"0\" max=\"100\" value=\"0\" style=\"flex:1\"><\/div>\n        <\/div>\n        <button id=\"vb-run\" style=\"width: 100%; padding: 12px; background: #2563eb; color: white; border: none; border-radius: 8px; font-size: 15px; font-weight: bold; cursor: pointer;\">\u540c\u6b65\u53c2\u6570\u5e76\u5f00\u59cb\u8fd0\u52a8\u6f14\u793a<\/button>\n        <div style=\"display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; font-size: 10px; font-weight: 700; margin-top:10px;\">\n            <span style=\"color:#ef4444\">\u2501 v\u2080<\/span> <span style=\"color:#3b82f6\">\u2501 v\u209c<\/span> <span style=\"color:#10b981\">\u2501 \u0394v(gt)<\/span> <span style=\"color:#8b5cf6\">\u2501 s<\/span> <span style=\"color:#94a3b8; text-decoration: underline;\">\u2501 \u7c97\u7ebf\u53c2\u8003\u7cfb<\/span>\n        <\/div>\n    <\/div>\n\n    <script>\n    (function() {\n        const root = document.getElementById('qiusir-projectile-bold-family-final');\n        const hIn = root.querySelector('#vb-h'), vIn = root.querySelector('#vb-v'), aIn = root.querySelector('#vb-a'), tIn = root.querySelector('#vb-t');\n        const ball = root.querySelector('#vb-ball'), activeTrace = root.querySelector('#vb-active-trace'), family = root.querySelector('#vb-family-layer'), fullTraceBg = root.querySelector('#vb-full-trace-bg');\n        const bestTrace = root.querySelector('#vb-best-trace'), bestLand = root.querySelector('#vb-best-land'), v0Fix = root.querySelector('#vb-vec-v0-fixed'), staticAn = root.querySelector('#vb-static-analysis');\n        const d_v0 = root.querySelector('#vb-dyn-v0'), d_vt = root.querySelector('#vb-dyn-vt'), d_dv = root.querySelector('#vb-dyn-dv'), d_sum = root.querySelector('#vb-dyn-sum'), sVec = root.querySelector('#vb-vec-s');\n        const aux1 = root.querySelector('#vb-dyn-aux-1'), aux2 = root.querySelector('#vb-dyn-aux-2');\n        \n        const g = 200, sX = 40, gY = 500, vScale = 0.4;\n        let curT = 0, isRun = 0, lastT = null;\n\n        const getPhys = (customAng = null) => {\n            const h = parseFloat(hIn.value), v0 = parseFloat(vIn.value), ang = (customAng !== null) ? customAng : parseFloat(aIn.value);\n            const rad = ang * Math.PI \/ 180, vx = v0 * Math.cos(rad), vy0 = -v0 * Math.sin(rad);\n            const disc = vy0 * vy0 + 2 * g * h, total = (disc >= 0) ? ((-vy0) + Math.sqrt(disc)) \/ g : 0;\n            return { vx, vy0, h, v0, rad, total, sY: gY - h, xEnd: vx * total };\n        };\n\n        const drawPath = (p, limitT = null) => {\n            const tMax = limitT !== null ? limitT : p.total;\n            let d = `M ${sX} ${p.sY}`; if(tMax <= 0) return d;\n            for(let i=0; i<=tMax; i += tMax\/40) d += ` L ${sX + p.vx * i} ${p.sY + p.vy0 * i + 0.5 * g * i * i}`;\n            return d + ` L ${sX + p.vx * tMax} ${p.sY + p.vy0 * tMax + 0.5 * g * tMax * tMax}`;\n        };\n\n        const refresh = () => {\n            const p = getPhys();\n            root.querySelector('#vb-plat').setAttribute('y', p.sY); root.querySelector('#vb-plat').setAttribute('height', p.h);\n            root.querySelector('#vb-origin-dot').setAttribute('cy', p.sY); \n            v0Fix.setAttribute('x1', sX); v0Fix.setAttribute('y1', p.sY); v0Fix.setAttribute('x2', sX + p.vx * vScale); v0Fix.setAttribute('y2', p.sY + p.vy0 * vScale);\n            fullTraceBg.setAttribute('d', drawPath(p));\n\n            let maxR = -1, bestA = 0;\n            for(let a = -15; a <= 85; a += 1) { let tp = getPhys(a); if(tp.xEnd > maxR) { maxR = tp.xEnd; bestA = a; } }\n            const bp = getPhys(bestA);\n            bestTrace.setAttribute('d', drawPath(bp));\n            bestLand.setAttribute('cx', sX + bp.xEnd); bestLand.setAttribute('cy', gY); bestLand.setAttribute('opacity', '1');\n\n            family.innerHTML = '';\n            [-15, 10, 50, 75].forEach(ang => {\n                const fp = getPhys(ang); const path = document.createElementNS(\"http:\/\/www.w3.org\/2000\/svg\", \"path\");\n                path.setAttribute('d', drawPath(fp)); path.setAttribute('stroke', '#cbd5e1'); \n                path.setAttribute('stroke-width', '3.5'); \/\/ \u7c97\u7ebf\u53c2\u8003\u7cfb\n                path.setAttribute('fill', 'none'); path.setAttribute('opacity', '0.2');\n                family.appendChild(path);\n            });\n\n            staticAn.innerHTML = '';\n            if (p.total > 0) {\n                [0.2, 0.4, 0.6, 0.8, 1.0].forEach(f => {\n                    const t = p.total * f, x = sX + p.vx * t, y = p.sY + p.vy0 * t + 0.5 * g * t * t;\n                    const vty = p.vy0 + g * t;\n                    const v0x_o = p.vx * vScale, v0y_o = p.vy0 * vScale, vtx_o = p.vx * vScale, vty_o = vty * vScale;\n                    const sumX_o = (p.vx*2)*vScale, sumY_o = (p.vy0+vty)*vScale;\n\n                    const drawL = (x1,y1,x2,y2,c,m,sw,da=null,op=\"0.6\") => {\n                        const ln = document.createElementNS(\"http:\/\/www.w3.org\/2000\/svg\", \"line\");\n                        ln.setAttribute('x1', x1); ln.setAttribute('y1', y1); ln.setAttribute('x2', x2); ln.setAttribute('y2', y2);\n                        ln.setAttribute('stroke', c); ln.setAttribute('stroke-width', sw); ln.setAttribute('opacity', op);\n                        if(da) ln.setAttribute('stroke-dasharray', da);\n                        if(m) ln.setAttribute('marker-end', `url(#${m})`); staticAn.appendChild(ln);\n                    };\n\n                    \/\/ \u9759\u6001\u7c07\u77e2\u91cf\u7ebf\u6761\u4fdd\u6301\u9ad8\u7cbe\u5ea6\uff08\u8f83\u7ec6\uff09\n                    drawL(x, y, x + v0x_o, y + v0y_o, '#ef4444', 'vb-arr-v0', '1.2'); \/\/ v0\n                    drawL(x, y, x + vtx_o, y + vty_o, '#3b82f6', 'vb-arr-vt', '1.2'); \/\/ vt\n                    drawL(x + v0x_o, y + v0y_o, x + vtx_o, y + vty_o, '#10b981', 'vb-arr-dv', '2', null, \"0.8\"); \/\/ \u0394v\n                    \n                    const v0tx = p.vx * t, v0ty = p.vy0 * t;\n                    drawL(sX, p.sY, sX + v0tx, p.sY + v0ty, '#ef4444', null, '1', '4,3', \"0.4\"); \/\/ v0t\n                    drawL(sX + v0tx, p.sY + v0ty, x, y, '#64748b', null, '1', '4,3', \"0.4\");     \/\/ 1\/2gt^2\n\n                    drawL(sX, p.sY, x, y, '#8b5cf6', 'vb-arr-s', '1.5', null, \"0.7\"); \/\/ s\n                    drawL(x, y, x + sumX_o\/2, y + sumY_o\/2, '#f59e0b', 'vb-arr-sum', '1.5', null, \"0.8\"); \/\/ 1\/2\u03a3v\n                });\n            }\n            update(curT);\n        };\n\n        const update = (t) => {\n            const p = getPhys(); let act = Math.min(t, p.total);\n            const x = sX + p.vx * act, y = p.sY + p.vy0 * act + 0.5 * g * act * act;\n            const curVy = p.vy0 + g * act;\n\n            ball.setAttribute('cx', x); ball.setAttribute('cy', y);\n            sVec.setAttribute('x1', sX); sVec.setAttribute('y1', p.sY); sVec.setAttribute('x2', x); sVec.setAttribute('y2', y);\n            activeTrace.setAttribute('d', drawPath(p, act));\n\n            const v0x_o = p.vx * vScale, v0y_o = p.vy0 * vScale, vtx_o = p.vx * vScale, vty_o = curVy * vScale;\n            \n            d_v0.setAttribute('x1', x); d_v0.setAttribute('y1', y); d_v0.setAttribute('x2', x + v0x_o); d_v0.setAttribute('y2', y + v0y_o);\n            d_vt.setAttribute('x1', x); d_vt.setAttribute('y1', y); d_vt.setAttribute('x2', x + vtx_o); d_vt.setAttribute('y2', y + vty_o);\n            d_dv.setAttribute('x1', x + v0x_o); d_dv.setAttribute('y1', y + v0y_o); d_dv.setAttribute('x2', x + vtx_o); d_dv.setAttribute('y2', y + vty_o);\n            d_sum.setAttribute('x1', x); d_sum.setAttribute('y1', y); d_sum.setAttribute('x2', x + (p.vx*vScale)); d_sum.setAttribute('y2', y + (p.vy0+curVy)*0.5*vScale);\n\n            aux1.setAttribute('x1', x + v0x_o); aux1.setAttribute('y1', y + v0y_o); aux1.setAttribute('x2', x + (p.vx*vScale)); aux1.setAttribute('y2', y + (p.vy0+curVy)*0.5*vScale);\n            aux2.setAttribute('x1', x + vtx_o); aux2.setAttribute('y1', y + vty_o); aux2.setAttribute('x2', x + (p.vx*vScale)); aux2.setAttribute('y2', y + (p.vy0+curVy)*0.5*vScale);\n\n            if(!isRun) tIn.value = (p.total > 0) ? (act \/ p.total) * 100 : 0;\n        };\n\n        const loop = (ts) => {\n            if(!isRun) return; if(!lastT) lastT = ts; curT += (ts - lastT) \/ 1000; lastT = ts;\n            const p = getPhys(); if(curT >= p.total) { curT = p.total; isRun = 0; }\n            update(curT); if(isRun) requestAnimationFrame(loop);\n        };\n\n        [hIn, vIn, aIn].forEach(el => el.oninput = () => { isRun = 0; refresh(); });\n        tIn.oninput = () => { isRun = 0; curT = (parseFloat(tIn.value)\/100) * getPhys().total; update(curT); };\n        root.querySelector('#vb-run').onclick = () => { if(curT >= getPhys().total) curT = 0; isRun = 1; lastT = null; requestAnimationFrame(loop); };\n        refresh();\n    })();\n    <\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u9ad8\u5ea6 H \u521d\u901f V\u2080 \u89d2\u5ea6 \u03b8 \u65f6\u95f4 T \u540c\u6b65\u53c2\u6570\u5e76\u5f00\u59cb\u8fd0\u52a8\u6f14\u793a \u2501 v\u2080 \u2501 v\u209c \u2501 \u0394v(gt) \u2501 s &#8230; <a title=\"qiutopIA\u629b\u4f53\u8fd0\u52a8\u89e3\u6790\" class=\"read-more\" href=\"https:\/\/www.qiusir.com\/?p=45387\" aria-label=\"\u9605\u8bfb qiutopIA\u629b\u4f53\u8fd0\u52a8\u89e3\u6790\">\u9605\u8bfb\u66f4\u591a<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[5],"tags":[443,247],"class_list":["post-45387","post","type-post","status-publish","format-standard","hentry","category-physics","tag-ai","tag-physics"],"_links":{"self":[{"href":"https:\/\/www.qiusir.com\/index.php?rest_route=\/wp\/v2\/posts\/45387","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.qiusir.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.qiusir.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.qiusir.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.qiusir.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=45387"}],"version-history":[{"count":13,"href":"https:\/\/www.qiusir.com\/index.php?rest_route=\/wp\/v2\/posts\/45387\/revisions"}],"predecessor-version":[{"id":45428,"href":"https:\/\/www.qiusir.com\/index.php?rest_route=\/wp\/v2\/posts\/45387\/revisions\/45428"}],"wp:attachment":[{"href":"https:\/\/www.qiusir.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=45387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.qiusir.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=45387"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.qiusir.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=45387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}