当前位置: 首页 > article >正文

Canvas指定三角形内部生成随机点

使用重心坐标(barycentric coordinates)或者通过面积比例的方法来确定点是否在三角形内。不过,对于简单的应用,一种常见的方法是使用随机点并检查它们是否在三角形内部。如果不在,就重新生成,直到得到足够数量的在三角形内的点。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Random Points in Triangle</title>
</head>
<body>
    <canvas id="myCanvas" width="500" height="500" style="border:1px solid #000000;"></canvas>
    <script>
        // 获取Canvas元素和绘图上下文
        var canvas = document.getElementById('myCanvas');
        var ctx = canvas.getContext('2d');

        // 定义三角形的三个顶点
        var vertex1 = { x: 50, y: 400 };
        var vertex2 = { x: 450, y: 50 };
        var vertex3 = { x: 50, y: 50 };

        // 检查点是否在三角形内部(使用面积法)
        function isPointInTriangle(px, py, v1, v2, v3) {
            var b1 = (py - v3.y) * (v2.x - v3.x) - (px - v3.x) * (v2.y - v3.y);
            var b2 = (py - v1.y) * (v3.x - v1.x) - (px - v1.x) * (v3.y - v1.y);
            var b3 = (py - v2.y) * (v1.x - v2.x) - (px - v2.x) * (v1.y - v2.y);
            return (b1 > 0 || b2 > 0 || b3 > 0) && (b1 < 0 || b2 < 0 || b3 < 0);
        }

        // 生成三角形内部的随机点
        function getRandomPointInTriangle(v1, v2, v3) {
            var r1, r2, s, t;

            // 生成两个0到1之间的随机数
            do {
                r1 = Math.random();
                r2 = Math.random();

                // 计算重心坐标
                s = r1;
                t = 1 - r1 - r2 * Math.sqrt(r1); // 确保t在0到1之间

                // 如果s+t+r2>1,则点在三角形外部,重新生成
            } while (s + t > 1);

            // 根据重心坐标计算点的位置
            var px = v1.x + s * (v2.x - v1.x) + t * (v3.x - v1.x);
            var py = v1.y + s * (v2.y - v1.y) + t * (v3.y - v1.y);

            return { x: px, y: py };
        }

        // 绘制三角形
        function drawTriangle(v1, v2, v3) {
            ctx.beginPath();
            ctx.moveTo(v1.x, v1.y);
            ctx.lineTo(v2.x, v2.y);
            ctx.lineTo(v3.x, v3.y);
            ctx.closePath();
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 1;
            ctx.stroke();
        }

        // 绘制指定数量的随机点
        function drawRandomPointsInTriangle(numPoints, v1, v2, v3) {
            ctx.fillStyle = 'red'; // 设置点的颜色

            for (var i = 0; i < numPoints; i++) {
                var point = getRandomPointInTriangle(v1, v2, v3);
                // 确保点在三角形内部(理论上getRandomPointInTriangle已经保证了这一点,但这里可以作为一个额外的检查)
                if (isPointInTriangle(point.x, point.y, v1, v2, v3)) {
                    ctx.beginPath();
                    ctx.arc(point.x, point.y, 2, 0, Math.PI * 2, true); // 绘制一个小圆作为点
                    ctx.fill();
                } else {
                    // 如果出于某种原因点不在三角形内(理论上不应该发生),则重新生成该点
                    i--; // 减少计数器,因为这次循环没有成功生成一个有效点
                }
            }
        }

        // 调用函数绘制三角形和随机点
        drawTriangle(vertex1, vertex2, vertex3); // 先绘制三角形
        drawRandomPointsInTriangle(10, vertex1, vertex2, vertex3); // 再绘制随机点
    </script>
</body>
</html>

http://www.kler.cn/a/452227.html

相关文章:

  • GoFrame框架介绍
  • 宏定义介绍
  • mysql双主双从
  • 《Mycat核心技术》第06章:Mycat问题处理总结
  • 短视频矩阵系统的视频批量剪辑源码技术开发,支持OEM
  • 人工智能ACA(七)——计算机视觉基础
  • Vue3入门(8)
  • THREE.js 入门(六) 纹理、uv坐标
  • 深入探索 npm cache clean --force:清理 npm 缓存的艺术
  • Python + 深度学习从 0 到 1(03 / 99)
  • Pyside6 在 pycharm 中的配置
  • 数据库 SQL 常用语句全解析
  • 瑞吉外卖项目学习笔记(八)修改菜品信息、批量启售/停售菜品
  • Matplotlib中隐藏坐标轴但保留坐标轴标签的3D图
  • 面经zhenyq
  • 图像处理-Ch5-图像复原与重建
  • 前端取Content-Disposition中的filename字段与解码(vue)
  • 「Java EE开发指南」如何用MyEclipse构建一个Web项目?(一)
  • 【Select 语法全解密】.NET开源ORM框架 SqlSugar 系列
  • CPU架构的变化史