马黑黑 发表于 2024-10-5 11:26

在线绘制多叶草——基于svg三次贝塞尔曲线路径

本帖最后由 马黑黑 于 2024-10-5 11:29 编辑 <br /><br /><style>
        #mama { margin: 20px auto; width: 760px; position: relative; }
        #mysvg { outline: 1px dashed gray; }
        #txtbox { padding: 8px; width: 740px; height: 120px; }
        #mama p { margin: 10px 0; }
        .tMid { text-align: center; }
</style>

<div id="mama">
        <p class="tMid">
                <svg id="mysvg" width="400" height="400" fill="olive" stroke="none">
                        <line x1="0" y1="50%" x2="100%" y2="50%" stroke="silver" stroke-dasharray="3" />
                        <line x1="50%" y1="0" x2="50%" y2="100%" stroke="silver" stroke-dasharray="3" />
                        <path id="svgpath" d="" fill="green" stroke="none" />
                </svg>
        </p>
        <blockquote>
                <p>
                        <label for="rngTotal">叶片总数 :</label>
                        <input id="rngTotal" type="range" min="3" max="20" value="3" />
                        <output id="o_total">3</output>
                </p>
                <p>
                        <label for="rngRadius">控点半径 :</label>
                        <input id="rngRadius" type="range" min="100" max="600" value="300" />
                        <output id="o_radius">300</output>
                </p>
                <p>
                        <label for="rngGapAngle">间隔角度 :</label>
                        <input id="rngGapAngle" type="range" min="10" max="60" value="20" />
                        <output id="o_gap">20</output>
                </p>
        </blockquote>
        <p>当前路径:</p>
        <p class="tMid"><textarea id="txtbox"></textarea></p>
</div>

<script>
drawPath = () => {
        let total = rngTotal.value * 1,
                r = rngRadius.value * 1,
                gapdeg = rngGapAngle.value * 1,
                deg = 360 / total,
                dstr = 'M200 200';
        for(i = 0; i < total; i++) {
                let x1 = 200 + r * Math.cos(i * deg * Math.PI / 180),
                        y1 = 200 + r * Math.sin(i * deg * Math.PI / 180),
                        x2 = 200 + r * Math.cos(i * deg * Math.PI / 180 + gapdeg),
                        y2 = 200 + r * Math.sin(i * deg * Math.PI / 180 + gapdeg);
                dstr += `C ${x1} ${y1}, ${x2} ${y2},200 200`;
        }
        svgpath.setAttribute('d', dstr);
        txtbox.value = dstr + "\n\n路径长度 :" + svgpath.getTotalLength();
};

const ranges = [, , ];
ranges.forEach(range => {
        range.oninput = () => {
                range.value = range.value;
                drawPath();
        };
});

drawPath();

</script>

马黑黑 发表于 2024-10-5 11:36

控点半径 :指三次贝塞尔曲线控制点离画布中心点的距离,画布尺寸为 400 * 400。控点半径会影响到多叶草叶片的高度。

间隔角度 :指三次贝塞尔曲线两个控制点间间隔的角度。角为第一控制点到画布中心点再到第二个控制点的连线。间隔角度作用于多叶草叶片的厚度。

不同的设置组合会得到不同的绘制效果,除了生成多叶草,还可以是奇离古怪的多肉乃至云朵、蘑菇等。

马黑黑 发表于 2024-10-5 11:37

初始页面所绘制的估计与玫瑰线相吻合,至少肉眼看去很接近

马黑黑 发表于 2024-10-5 11:38

得到 d 属性值后,可以将该路径用做自己设计的图案

花飞飞 发表于 2024-10-5 12:15

马黑黑 发表于 2024-10-5 11:37
初始页面所绘制的估计与玫瑰线相吻合,至少肉眼看去很接近

又听到一个美术新名词儿。。三秒一下,原来玫瑰线是一种花瓣曲线。。怪好听的

花飞飞 发表于 2024-10-5 12:16

马黑黑 发表于 2024-10-5 11:38
得到 d 属性值后,可以将该路径用做自己设计的图案

这个简直是万能了,把花瓣形曲线一网打尽,几乎所有的形状都可以用这个小工具得到。。

花飞飞 发表于 2024-10-5 12:20

马黑黑 发表于 2024-10-5 11:36
控点半径 :指三次贝塞尔曲线控制点离画布中心点的距离,画布尺寸为 400 * 400。控点半径会影响到多叶草叶 ...

数量和角度相结合,能得到各种意想不到的形状,惊奇。。
超实用工具。。
以前的canvas画布可以绘制多叶草,这个更牛,样式更多。。

马黑黑 发表于 2024-10-5 12:22

花飞飞 发表于 2024-10-5 12:20
数量和角度相结合,能得到各种意想不到的形状,惊奇。。
超实用工具。。
以前的canvas画布可以绘制多叶 ...

实现机制不同

马黑黑 发表于 2024-10-5 12:24

花飞飞 发表于 2024-10-5 12:15
又听到一个美术新名词儿。。三秒一下,原来玫瑰线是一种花瓣曲线。。怪好听的

玫瑰线又叫风玫瑰,最初与航海有关

马黑黑 发表于 2024-10-5 12:25

花飞飞 发表于 2024-10-5 12:16
这个简直是万能了,把花瓣形曲线一网打尽,几乎所有的形状都可以用这个小工具得到。。

不会吧?一切基于多叶草

红影 发表于 2024-10-5 12:44

间隔角度 :指三次贝塞尔曲线两个控制点间间隔的角度。角为第一控制点到画布中心点再到第二个控制点的连线。间隔角度作用于多叶草叶片的厚度。

这个很神奇,只要相差1度,形状就大相径庭。还可以这样设置啊,还以为两个控制点只能用坐标表示,这个是用角度反算上去的么?

红影 发表于 2024-10-5 12:45

这里的取值尾数保留这么多位啊,真够精确的{:4_187:}

红影 发表于 2024-10-5 12:46

上面的三个数字依次取了 10 400 41得到的图形好奇妙{:4_204:}

红影 发表于 2024-10-5 12:50

三个数字只调其中一个,发现很多图形是交替出现的,应该是里面有内在规律的。

红影 发表于 2024-10-5 12:51

这个在线工具太牛了,可以使用计算机强大的计算能力,得到很多意想不到的效果呢{:4_199:}

梦江南 发表于 2024-10-5 15:14

老师辛苦了!

马黑黑 发表于 2024-10-5 15:56

红影 发表于 2024-10-5 12:44
间隔角度 :指三次贝塞尔曲线两个控制点间间隔的角度。角为第一控制点到画布中心点再到第二个控制点的连线 ...

角度的变化会改变控制点的位置

马黑黑 发表于 2024-10-5 15:56

红影 发表于 2024-10-5 12:45
这里的取值尾数保留这么多位啊,真够精确的

不做处理,保留计算出来的原始数值

马黑黑 发表于 2024-10-5 15:57

红影 发表于 2024-10-5 12:50
三个数字只调其中一个,发现很多图形是交替出现的,应该是里面有内在规律的。

是的

马黑黑 发表于 2024-10-5 15:57

梦江南 发表于 2024-10-5 15:14
老师辛苦了!

{:4_190:}
页: [1] 2 3 4 5 6
查看完整版本: 在线绘制多叶草——基于svg三次贝塞尔曲线路径