首页 > 其他分享 >HTML 中用 js 画出谢尔宾斯基三角形 Sierpinski triangle ( chaos 画法)

HTML 中用 js 画出谢尔宾斯基三角形 Sierpinski triangle ( chaos 画法)

时间:2023-11-27 16:13:18浏览次数:40  
标签:function p1 return Sierpinski top 谢尔宾 let triangle defaultPoint

谢尔宾斯基三角形(英语:Sierpinski triangle)是一种分形,由波兰数学家谢尔宾斯基在1915年提出。它是自相似集的例子。它的豪斯多夫维是log(3)/log(2) ≈ 1.585。


随机的绘画方法
先定三点ABC使其构成一个没有边的等边三角形

然后在三角形内随机定一个点P

然后在ABC 随机 选择一个点
然后在此点与P点的中间画一个点nP

再从ABC 随机 选择一个点
再此点与nP点的中间画一个点P
重复...


        <div class="continer">
            <canvas id="game" width="500" height="500"></canvas>
            <button id="next">画出下一个点</button>
        </div>
        <script type="text/javascript">
            var canvas = document.getElementById('game');
            var next = document.getElementById("next");
            var ctx = canvas.getContext('2d');
            const fix = 1; //保留小数点后一位
            var pointSize = 1;//点的大小
            //坐标工厂
            function Point(x, y) {
                if (x == null) {
                    x = -1;
                }
                if (y == null) {
                    y = -1;
                }
                return {
                    x,
                    y,
                    toString() {
                        return '[' + x + ',' + y + ']'
                    }
                };
            }
            //斜率计算
            function K(p1, p2) {
                if (p1 == null) {
                    console.log("计算斜率需要两个坐标-缺少p1");
                    return;
                }
                if (p2 == null) {
                    console.log("计算斜率需要两个坐标-缺少p2");
                    return;
                }
                return ((p2.y - p1.y) / (p2.x - p1.x)).toFixed(fix);
            }
            //----------------------------------------------------------------------------//
            //等边三角形的默认三个点
            var defaultPoint = {
                top: function() {
                    return new Point(250, 20);
                },
                height: 320,
                left: function() {
                    return new Point(
                        (this.top().x - (Math.sqrt(3) * this.height / 3)).toFixed(fix),
                        this.top().y + this.height
                    );
                },
                right: function() {
                    return new Point(
                        (this.top().x + (Math.sqrt(3) * this.height / 3)).toFixed(fix),
                        this.top().y + this.height
                    );
                },
                toString() {
                    return "{\n" + 't[' + this.top().x + "," + this.top().y + ']' + "\n" +
                        'r[' + this.right().x + "," + this.right().y + ']' + '\n' +
                        'l[' + this.left().x + "," + this.left().y + ']' + '\n' + '}';
                }
            }
            //初始化函数
            function init(){
                ctx.fillStyle = '#23a0ff';
                //ctx.strokeRect(0, 0, 300, 300); //边框
                ctx.fillRect(defaultPoint.top().x, defaultPoint.top().y, pointSize, pointSize);
                ctx.fillRect(defaultPoint.left().x, defaultPoint.left().y, pointSize, pointSize);
                ctx.fillRect(defaultPoint.right().x, defaultPoint.right().y, pointSize, pointSize);
                
                //ctx.strokeText('t', defaultPoint.top().x, defaultPoint.top().y - 5); //点1位置
                //ctx.strokeText('l', defaultPoint.left().x, defaultPoint.left().y + 15); //点2位置
                //ctx.strokeText('r', defaultPoint.right().x, defaultPoint.right().y + 15); //点3位置
                
            }
            
            //生成从minNum到maxNum的随机数
            function randomNum(x, y) {
                return Math.round(Math.random()*(Number(y)-Number(x))+Number(x));
            }

            //在此直线中放一个点,参数是两个点——由此两点得出的直线函数
            function putPointOnLineByRandom(p1, p2) {
                //直线范围:|p1.x| -- |p2.x|
                //两点式: (y - y1) / (y2 - y1) = (x - x1) / (x2 - x1)
                //一般式: 0 = (x - x1) / (x2 - x1) - (y - y1) / (y2 - y1)
                //点斜式: (y - y1) = k(x - x1)
                //一般式: 0 = k(x - x1) - (y - y1)
                let rx;
                //生成随机20
                rx = randomNum(p1.x, p2.x);

                let k = K(p1, p2); //算出斜率
                let b =  p1.y -k * p1.x ; //寻找B

                //let y = k*(rx)-p1.y + b
                let y = k * rx + b;
                ctx.fillRect(rx, y, pointSize, pointSize);
                return new Point(rx, y);
            }
            //在两点构成的线中的中点画一个点
            function putPointOnLineMid(p1,p2){
                let x = (Number(p1.x)+Number(p2.x))/2.0;
                let y = (Number(p1.y)+Number(p2.y))/2.0;
                ctx.fillRect(x, y, pointSize, pointSize);
                return new Point(x,y);
            }
            //保存三个边的符号,方便随机挑一个
            let sides = ['a','b','c'];
            //随机在side边上放一个点
            function put(side) {
                //l->t的为a边
                //t->r的为b边
                //r->l的为c边
                switch (side) {
                    case 'a':
                    return putPointOnLineByRandom(defaultPoint.left(), defaultPoint.top());
                        break;
                    case 'b':
                    return putPointOnLineByRandom(defaultPoint.top(), defaultPoint.right());
                        break;
                    case 'c':
                    return putPointOnLineByRandom(defaultPoint.left(), defaultPoint.right());
                        break;
                }
            }
            //保存上一次画的点
            let lastPoint;
            //画出第一个点在此三角形的某一边中
            function putFirst(){
                lastPoint = put(sides[randomNum(0,2)]);
            }
            //初始化等边三角形的三个点
            init();
            //画出第一个点在此三角形的某一边中
            putFirst();
            //保存三个点的坐标,方便随机挑
            let dpt = [
                new Point(defaultPoint.top().x,defaultPoint.top().y),
                new Point(defaultPoint.left().x,defaultPoint.left().y),
                new Point(defaultPoint.right().x,defaultPoint.right().y),
            ]
            //最终执行
            function excute() {
                let chose = randomNum(0,2);
                let target = dpt[chose];
                lastPoint = putPointOnLineMid(lastPoint,target);
            }
            //手动画,亲自体验(不保证鼠标不会被点坏)
            next.onclick = function(){
                excute();
            };
            //自动执行
            function aotu(){
                for(let n = 0;n<100000;n++){
                    setTimeout(() => {
                        excute();
                    }, 1500);
                }
            }
            aotu();
        </script>

image

标签:function,p1,return,Sierpinski,top,谢尔宾,let,triangle,defaultPoint
From: https://www.cnblogs.com/yueyingyifeng/p/17859594.html

相关文章

  • 根据三条边的长度在线生成三角形(generate triangles by edge lengths)
     网址:https://www.geogebra.org/m/JHgTXKrt 方法:鼠标拖放端点可以改变端点的长度和位置。 网址:https://www.mathwarehouse.com/triangle-calculator/online.php 方法:输入三条边的长度,生成三角形。 ......
  • CF1025F Disjoint Triangles
    虽然我不懂计算几何,但是两个三角形互相进入,感觉很涩啊!——By【】考虑两个互不相交的三角形,寻找一个方式能够不重不漏地统计它们。容易发现两条不交的线段\(A_1A_2,B_1B_2\)之间,必然存在一条直线将\(A_1A_2,B_1B_2\)分在直线两端,且与\(A_1A_2,B_1B_2\)无交。证明的话,......
  • 不修改Read/Write Enabled,Texture.GetPixels,Mesh.triangles
    ###原理:将Texture拷贝一份出来然后读取///<summary>///不通过设置Read/WriteEnabled,直接克隆一份可读的Texture2D///</summary>///<paramname="source"></param>///<returns></returns>publicstaticTexture2DCloneTexture......
  • CF553C Love Triangles
    很有意思的一个题,想了一会才发现解题的关键首先我们注意到对于某个大小\(\ge3\)的连通块,其实连通块内的所有边的颜色都会被已知的边唯一确定而不同的连通块间的连边方式有两种,因此设连通块个数为\(tot\),最后的答案就是\(2^{tot-1}\)但还要考虑判掉不合法的情况,注意到不管是\(1......
  • Triangle Graph Interest Network for Click-through Rate Prediction
    目录概TGINMotivation:Triangle的重要性Model代码JiangW.,JiaoY.,WangQ.,LiangC.,GuoL.,ZhangY.,SunZ.,XiongY.andZhuY.Trianglegraphinterestnetworkforclick-throughrateprediction.WSDM,2022.概'图'用于精排,但是这里的图的使用主要是基于......
  • 题解 [ABC258G] Triangle
    题目链接\(\rmO(n^3)\)枚举\(i,j,k\)的算法是显然的。考虑优化掉一个\(n\),如果枚举\(i,j\),那么显然需要找出有多少个\(k\)同时满足\(a_{i,k}=a_{j,k}=1\),我们可以将\(a_i\)和\(a_j\)看作两个二进制数,那么同时等于\(1\)的位置就是并起来等于\(1\)的位置,\(bitset......
  • OpenGL之DrawTriangle
    1/*第一步:引入相应的库*/2#include<iostream>3usingnamespacestd;45#defineGLEW_STATIC6#include<GL/glew.h>7#include<GLFW/glfw3.h>8910/*第二步:编写顶点位置*/11GLfloatvertices_1[]=12{130.0......
  • CF1842E Tenzing and Triangle - 线段树优化 dp -
    题目链接:https://codeforces.com/contest/1842/problem/E题解:首先,如果两个等腰三角形相交了,那答案肯定不会更优。因此不会相交。先考虑一个\(n^2\)的dp:设\(dp_i\)表示考虑到\(x=i\)时的最小代价,首先可以先都加一个\(\sumc_i\),这样只需要考虑三角形覆盖范围内的\(c_i......
  • CodeForces 1842E Tenzing and Triangle
    洛谷传送门CF传送门一个很显然的观察:选择的三角形两两重叠面积为\(0\),否则合并更优。考虑dp,设\(f_i\)为删完\(x_j\gei\)的所有点的最小花费。转移就枚举选择的三角形直角边长\(l\),那么\(f_i=\min(f_{i+1}+\sum\limits_{x_p=i}c_p,\min\limits_lf_{i+l}......
  • 120. Triangle刷题笔记
    用DP可以做完classSolution:defminimumTotal(self,triangle:List[List[int]])->int:dp=[0]*(len(triangle)+1)forrowintriangle[::-1]:foriinrange(len(row)):dp[i]=row[i]+min(dp[i],dp[i+1])ret......