在画布上绘制箭头,需要的效果如下图:

分解这个图形可以由一个梯形、三角形组成,剩下的就是需要计算三角形、梯形各个顶点的坐标了,这里就是比较麻烦的地方,说白了也是个数学问题,搞懂原理,剩下的就是工作量了。
对图形进行分解,如下图:

r(x,y)点旋转一个角度α,到B(x,y),计算B点的坐标公式:

bx=R*cos(α)+rx;
by=R*sin(α)+ry;

看明白了这个公式,套用到箭头中,就可以简单的算个各个顶点的坐标了,核心代码如下:

/*** 绘制箭头** @param canvas 画布* @param sx     起点x* @param sy     起点y* @param ex     终点x* @param ey     终点y* @param paint  画笔*/
public static void drawArrow(Canvas canvas, float sx, float sy, float ex, float ey, Paint paint) {float px = ex - sx; //两点x间距离float py = ey - sy; //两点y间距离float arrowSize = paint.getStrokeWidth(); //箭头高度double H = arrowSize; // 箭头高度 Hdouble L = arrowSize / 2; // 箭头底边 L 的长度double awrad = Math.atan(L / 2 / H); // 箭头角度double arraow_len = Math.sqrt(L / 2 * L / 2 + H * H) - 5; // 箭头所在的斜边长double[] arrXY_1 = rotateVec(px, py, awrad, true, arraow_len);double[] arrXY_2 = rotateVec(ex - sx, py, -awrad, true, arraow_len);float x2 = (float) (ex - arrXY_1[0]); // (x2,y2)是第二端点float y2 = (float) (ey - arrXY_1[1]);float x3 = (float) (ex - arrXY_2[0]); // (x3,y3)是第三端点float y3 = (float) (ey - arrXY_2[1]);double TL = L / 2;  //梯形短边长度arraow_len = Math.sqrt(px * px + py * py);awrad = Math.atan(TL / 2 / arraow_len); // 箭头角度double[] T1 = rotateVec(px, py, awrad, true, arraow_len);double[] T2 = rotateVec(px, py, -awrad, true, arraow_len);float tx1 = (float) (ex - T1[0]);float ty1 = (float) (ey - T1[1]);float tx2 = (float) (ex - T2[0]);float ty2 = (float) (ey - T2[1]);// 画线Path linePath = new Path();linePath.moveTo(sx, sy);linePath.lineTo(tx1, ty1);linePath.lineTo(x2, y2);linePath.lineTo(x3, y3);linePath.lineTo(tx2, ty2);linePath.close();canvas.drawPath(linePath, paint);awrad = Math.atan(L / H); // 箭头角度arraow_len = Math.sqrt(L * L + H * H); // 箭头的斜边长arrXY_1 = rotateVec(px, py, awrad, true, arraow_len);arrXY_2 = rotateVec(px, py, -awrad, true, arraow_len);x2 = (float) (ex - arrXY_1[0]); // (x2,y2)是第二端点y2 = (float) (ey - arrXY_1[1]);x3 = (float) (ex - arrXY_2[0]); // (x3,y3)是第三端点y3 = (float) (ey - arrXY_2[1]);Path triangle = new Path();triangle.moveTo(ex, ey);triangle.lineTo(x2, y2);triangle.lineTo(x3, y3);triangle.close();canvas.drawPath(triangle, paint);
}/*** 计算 向量(px,py) 旋转ang角度后的新长度** @return*/
public static double[] rotateVec(float px, float py, double ang, boolean isChLen, double newLen) {double mathstr[] = new double[2];// 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度�?�新长度double vx = px * Math.cos(ang) - py * Math.sin(ang);double vy = px * Math.sin(ang) + py * Math.cos(ang);if (isChLen) {double d = Math.sqrt(vx * vx + vy * vy);vx = vx / d * newLen;vy = vy / d * newLen;}mathstr[0] = vx;mathstr[1] = vy;return mathstr;
}

Canvas绘制箭头相关推荐

  1. Canvas学习:封装Canvas绘制基本图形API

    Canvas学习:封装Canvas绘制基本图形API Canvas Canvas学习 从前面的文章中我们了解到,通过Canvas中的CanvasRenderingContext2D对象中的属性和方法, ...

  2. Android Canvas绘制带箭头的直线

    先看下效果图: 下面我们直接看代码 我自定义了一个View,代码如下: package com.davis.drawtrangle;import android.content.Context; im ...

  3. Canvas学习:绘制箭头

    原文出处:https://www.w3cplus.com/canvas/drawing-arrow.html (本文对错误做了纠正,博主有一系列实用Canvas教程) 在这篇文章中主要来聊在Canva ...

  4. 在canvas中绘制箭头

    canvas中没有提供绘制箭头的函数,需要自己手动绘制,幸好箭头并不复杂,简单来说箭头由三条线段组成,如下图所示,线段AB.BC和BD,关键在于在给定端点A和B的坐标情况下,如何计算点C和D的坐标. ...

  5. canvas绘制经典折线图(一)

    最终效果图如下: 实现步骤如下:注-引用了jQuery HTML代码 <!doctype html> <html lang="en"> <head&g ...

  6. html canvas绘制网格,canvas(七)绘制网格和坐标轴

    ###1.绘制网格 var canvas = document.querySelector("canvas") var ctx = canvas.getContext(" ...

  7. Canvas 绘制直线

    Canvas 绘制直线 1.canvas绘图是一种基于状态的绘图,绘图的过程应该是先设置绘图的状态,再调用具体的函数进行绘制. 例如绘制一条(100,100)到(700,700)的直线: contex ...

  8. python制作简单动画_Python tkinter Canvas绘制动画

    其实前面程序中的高亮显示已经是动画效果了.程序会用红色.黄色交替显示几何图形的边框,这样看上去就是动画效果了.实现其他动画效果也是这个原理,程序只要增加一个定时器,周期性地改变界面上图形项的颜色.大小 ...

  9. H5 Canvas绘制三角函数图像

    三角函数sin.cos.tan.sinh.cosh.tanh js 的Math库,自带了许多常见函数方法,其中关于 三角函数的求解还是很齐全的,于是想到,利用canvas 绘制一个比较准确的 sin. ...

最新文章

  1. 柔性生态布局未来,小鱼易连 2019“深耕视界逐梦小鱼”北京火爆招募
  2. MockDialog
  3. 手机4k读写速度测试软件,4K扇区速度测试及读写IOPS_Intel 520_固态硬盘评测-中关村在线...
  4. [JAVA基础类库] Objec类
  5. Call for Papers | 2019 年 IEEE 国际进化计算大会
  6. Vue.js——60分钟组件快速入门(上篇)
  7. 第二十二章 5为你的命名空间取个别名
  8. 点击Result list里product ID出现白屏的又一原因及分析
  9. 如何编写更好的POJO服务
  10. Gnofract 4D 3.0
  11. python学习(10)字典学习,写一个三级菜单程序
  12. Linux下C语言编程入门-8关于计时器
  13. ARM的开发步骤:让你思路更清晰
  14. python 豆瓣源安装_python pip使用豆瓣源技巧和pip配置文件更改豆瓣源
  15. qt在window实现二维码识别
  16. CSS实现元素width右方向变化、左方向变化、双向变化
  17. 风影ASP.NET基础教学16 母版页
  18. 汽车站车票管理系统(课程作业)
  19. 衡水中学2021高考成绩查询,清华公布2021“丘班”学生名单,多所重点高中入选,唯独没有衡中...
  20. ace布置小作业: 制作一个简单的电话号码归属地查询软件:JSON解析和Volly发送get请求...

热门文章

  1. 5分钟使用Echarts轻松实现地图下钻
  2. PAT编程(python) 1004 成绩排名
  3. 事件抽取(event extraction)
  4. 帐篷混沌映射在优化算法中的应用
  5. SQL 简介以及MySQL的优点
  6. 2020-10-1 //严蔚敏《数据结构》 //赫夫曼树及其应用:创建顺序赫夫曼树创建及得到赫夫曼编码
  7. 指数函数误差平方和matlab,数值分析与实验数学081 张燃 3080801119).doc
  8. HTML表格,列表,超链接,图片
  9. 超过100项改进 100tv聚好看全新发布
  10. STM32驱动PCF8563,使用模拟IIC