文档章节

canvas-任意画多个凸多边形

duduYZ
 duduYZ
发布于 2017/07/19 11:42
字数 666
阅读 236
收藏 0

项目中需要用到鼠标点画任意多个角的凸多边形,不允许有凹进去的角,思路是用到直线方程判断落点的位置,前两个点可以任意落点,从第三个点开始起进行判断,如果落点与之前的点结合之后形成的是凹进去的角,则不允许落点,单击画点,双击闭合路径,代码如下:

html:

<canvas id="canvas" width="800" height="500">当前浏览器不支持canvas,请更换浏览器使用!</canvas>

直接使用canvas标签

js:

    var canvas = document.getElementById("canvas") //获取到canvas元素
    var context = canvas.getContext("2d") //获取上下文的环境

    function drawPoint(cxt, x, y, w, borderWidth, borderColor, fillColor) {
        cxt.beginPath()
        cxt.moveTo(x - w, y - w)
        cxt.lineTo(x + w, y - w)
        cxt.lineTo(x + w, y + w)
        cxt.lineTo(x - w, y + w)
        cxt.lineWidth = borderWidth
        cxt.strokeStyle = borderColor
        cxt.fillStyle = fillColor
        cxt.closePath()
        cxt.fill()
        cxt.stroke()
    }

    function drawPolygon(cxt, dbl, borderWidth, borderColor, fillColor, t) {
        for (var i = 0; i < dbl.length; i++) {
            drawPoint(cxt, dbl[i].x, dbl[i].y, 2, 1, 'red', 'skyblue')
        }
        cxt.moveTo(dbl[0].x, dbl[0].y)
        for (var i = 1; i < dbl.length; i++) {
            cxt.lineTo(dbl[i].x, dbl[i].y)
        }
        if (t) {
            cxt.closePath()
            cxt.fillStyle = fillColor
            cxt.fill()
        }
        cxt.lineWidth = borderWidth
        cxt.strokeStyle = borderColor
        cxt.stroke()
    }

    function z(x, y, x1, y1, x2, y2) {
        if (((x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)) > 0) {
            return 1
        } else if (((x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)) < 0) {
            return 3
        } else {
            return 2
        }
    }

获取到canvas之后,定义画点和连线以及闭合路径的函数

var timeId;
    var dbl = [], arr = []
    canvas.ondblclick = function () {
        if (arr.length > 2) {
            drawPolygon(context, arr, 1, 'red', "rgba(0, 0, 0, .1)", true)
            // 这里执行完成闭合之后,清空坐标数组,便于另外新建
            dbl = arr
            arr = []
        }
    }
    canvas.onclick = function (e) {
        clearTimeout(timeId);
        timeId = setTimeout(function () {
            x = e.offsetX
            y = e.offsetY
            if (arr.length >= 3) {
                var n1= z(arr[2].x, arr[2].y, arr[0].x, arr[0].y, arr[1].x, arr[1].y)
                var n2 = z(arr[arr.length - 1].x, arr[arr.length - 1].y, arr[0].x, arr[0].y, x, y) 
                var n3= z(arr[1].x, arr[1].y, arr[0].x, arr[0].y, x, y)
                var n4= z(arr[arr.length - 1].x, arr[arr.length - 1].y, arr[arr.length - 2].x, arr[arr.length - 2].y, x, y)
                if (n1=== 1) {
                    // 代表第2点在线左边,这时判断第4个点的位置,如果在左边就不允许落点
                    if (n2 === 1 || n3=== 1 || n4=== 1) {
                        return
                    }
                }
                if (n1=== 3) {
                    // 代表第2点在线右边,这时判断第4个点的位置,如果在右边就不允许落点
                    if (n2 === 3 || n3=== 3 || n4=== 3) {
                        return
                    }
                }
                arr.push({x: x, y: y})
            }
            arr.length < 3 ? arr.push({x: x, y: y}) : null
            drawPolygon(context, arr, 1, 'blue')

        }, 250)

    }

根据判断落点位置的函数来进行落点位置的控制,最后双击进行闭合路径填充颜色,另外项目里还有用到画任意数量大小矩形,思路也是差不多的,我是通过的鼠标点击后移动鼠标来实现控制

© 著作权归作者所有

duduYZ
粉丝 2
博文 121
码字总数 38104
作品 0
海淀
私信 提问
Vue + Canvas项目总结

演示地址 演示地址 PC端的项目啦,需要在电脑上看哦,而且最好用Chrome打开 引言 这是今年三月份帮学长做的一个项目,陪我度过了两个月的春招生活,整个项目做下来也是学到了很多东西,下面就...

雪碧亦作酒
2018/07/24
0
0
【转】2019春季阿里笔试算法题——判断一个点是否在多边形内部

题目描述: 自己任意输入几个点构造一个多边形,然后再随机输入一个点,判断该点是否在多变形里面,如果不在,那么该点离多变形的最短距离是多少。 思路一: 下面是几个比较基本的方法: (1...

Jinlong_Xu
07/17
0
0
常见凸多边形判断方法

凸多边形的判定方法 在计算几何和地理信息系统中,多边形的凹凸性判定十分重要。那么什么是凹多边形和凸多边形呢?首先,我们从直观上来理解,凸多边形就是多边形任意两个顶点的连线在多边形...

长平狐
2013/12/25
444
0
Codility每周一课:P99.5 PolygonConcavityIndex

P99.5 PolygonConcavityIndex Check whether a given polygon in a 2D plane is convex; if not, return the index of a vertex that doesn't belong to the convex hull. P99.5 凸包内点 判......

AiFan
03/21
0
0
读《思维的乐趣matrix67数学笔记》

今天是我第一次听说这个故事。 1933 年,匈牙利数学家 George Szekeres 还只有 22 岁。那时,他常常和朋友们在匈牙利的首都布达佩斯讨论数学。这群人里面还有同样生于匈牙利的数学怪才——P...

pricker
2015/09/24
73
0

没有更多内容

加载失败,请刷新页面

加载更多

Eureka应用注册与集群数据同步源码解析

在之前的EurekaClient自动装配及启动流程解析一文中我们提到过,在构造DiscoveryClient类时,会把自身注册到服务端,本文就来分析一下这个注册流程 客户端发起注册 boolean register() t...

Java学习录
18分钟前
4
0
Java描述设计模式(15):责任链模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景描述 1、请假审批流程 公司常见的请假审批流程:请假天数 当 day<=3 天,项目经理审批当 3<day<=5 天,部门经理审批当 day>5 天...

知了一笑
29分钟前
6
0
总结:数组与链表

1、内存申请:数组在内存上是连续的空间;链表,内存地址上可以是不连续的。 2、查询速度:数组可以随机访问,链表必须顺序访问,即从首个元素开始遍历,逐个查找,所以数组查询很快。 3、写入...

浮躁的码农
37分钟前
6
0
HashMap源码分析

read

V丶zxw
56分钟前
5
0
Python字符串或JSON字符串转字典dict、列表list

有3种方法 1、使用ast模块 >>> import ast>>> s = '["test",1]'>>> ast.literal_eval(s)['test',1]>>> s = '{"test":1}'>>> ast.literal_eval(s){'test': 1} 2、eval函数,这个......

编程老陆
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部