matlab 画中垂线,zrender 绘制带有中垂线的线段
zrender(Zlevel Render) 是一个轻量级的Canvas类库,绘制直线是很简单的事情,但是绘制中垂线还需借助到数学知识「三角函数」。
y ^
| B(x1, y1)
| /┆
| / ┆
| / ┆
| / ┆
|/----┼----+ F
/ C \┆
/| ┆\D
/ | ┆
——————————/——+—————┼———+————————> x
/ |O ┆ E
/ | ┆
/_____|_____┆
A(x, y) | G
|
设平面坐标系 xoy 中,有线段 A(x, y)、B(x1, y1),计算出垂直于 AB 线段中点 C 上一侧的长度为 n 的线段 CD 两端点坐标
1:算出线段 AB 的长度:
2:算出中点 C 的坐标:
3:设过坐标原点 o 的长度为 n 的线段 OE,在 x 轴的正坐标上,则两点坐标为:O(0, 0),E(n, 0)
4:将 OE 平移至 C 点且 O 与 C 重合,得到 CF,则 F 点的坐标为:xf = n + xc; yf = yc
5:运用三角函数,计算各个角的关系
6:线段 AB 与 x 轴的夹角:
;
7:通过三角函数关系可计算,XY平面中一点(x1,y1)经圆周旋转θ角度,得到点(x2,y2),公式如下
8:将 F 点经圆周旋转 ∠FCD 之后,得到 D 点
实现代码:
/**
* 绊线
* @ start[ ] 开始点坐标
* @ end[ ] 结束点坐标
* @ direction[ ] 箭头方向坐标(以一个点的坐标代替)
* @ around `(String)` 箭头包围方式:single - 单侧;double - 双侧
*
* @return
* 当 around 为 "single" 时,在绘制结束后,取 `shape.site` 可得到箭头在线段的哪一侧;
* 返回 "left" 或 "right"
*/
var TripWire = zrender.Path.extend({
type: 'TripWire',
shape: {
start: [0, 0],
end: [0, 0],
direction: [0, 0],
around: 'single', // or double, set the arrow site, single is left or right on the line, double is on the left and right
side: null
},
style: {
stroke: '#000',
fill: 'rgba(0, 0, 255, 0.2)'
},
buildPath: function (ctx, shape) {
// 起点坐标
var x1 = shape.start[0]
var y1 = shape.start[1]
// 终点坐标
var x2 = shape.end[0]
var y2 = shape.end[1]
// 方向坐标(单向有效)
var x3 = shape.direction[0]
var y3 = shape.direction[1]
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
// console.log("线段坐标", x1, y1, x2, y2)
console.log(shape.side)
if (!shape.side || shape.side == null || (shape.side !== 'left' && shape.side !== 'right')) {
// 计算箭头所在线段哪一侧,先计算一个点相对线段的向量,>0 左侧,<0 右侧,=0 线上
var vector = (x1 - x3) * (y2 - y3) - (y1 - y3) * (x2 - x3)
console.log(vector)
// 返回箭头所在方位
if (shape.around === 'single') {
if (vector < 0) {
shape.site = 'left'
} else {
shape.site = 'right'
}
}
} else {
shape.site = shape.side
}
// console.log("向量", vector);
// TODO
/**
* y ^
* | B(x1, y1)
* | /┆
* | / ┆
* | / ┆
* | / ┆
* |/----┼----+ F
* / C \┆
* /| ┆\D
* / | ┆
* ——————————/——+—————┼———+————————> x
* / |O ┆ E
* / | ┆
* /_____|_____┆
* A(x, y) | G
* |
*
* 设平面坐标系 xoy 中,有线段 A(x, y)、B(x1, y1),计算出垂直于 AB 线段中点 C 上一侧的长度为 n 的线段 CD 两端点坐标
* _________________________
* 1:算出线段 AB 的长度:|AB| = √ (x - x1)^2 + (y - y1)^2
*
* 2:算出中点 C 的坐标:xc = x1 + (x - x1) / 2; yc = y1 + (y - y1) / 2
*
* 3:设过坐标原点 o 的长度为 n 的线段 OE,在 x 轴的正坐标上,则两点坐标为:O(0, 0),E(n, 0)
*
* 4:将 OE 平移至 C 点且 O 与 C 重合,得到 CF,则 F 点的坐标为:xf = n + xc; yf = yc
*
* 5:运用三角函数,计算各个角的关系
*
* 6:线段 AB 与 x 轴的夹角:sin(∠BAG) = sin(∠BCF) = cos(∠FCD) = BG/AB;
* cos(∠BAG) = cos(∠BCF) = sin(∠FCD) = AG/AB
*
* 7:通过三角函数关系可计算,XY平面中一点(x1,y1)经圆周旋转θ角度,得到点(x2,y2),公式如下
* x2 = x1 * cos(θ) - y1 * sin(θ)
* y2 = x1 * sin(θ) + y1 * cos(θ)
*
* 8:将 F 点经圆周旋转 ∠FCD 之后,得到 D 点
*
*/
// 线段长度
var ABLength = Math.abs(Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2)))
// console.log("leng", ABLength);
// 线段中心点
var center_x1 = (x2 - x1) / 2 + x1
var center_y1 = (y2 - y1) / 2 + y1
// console.log("center", center_x1, center_y1);
// 设长度为100px的线段 OE 经过坐标原点,且 O 点在坐标原点上,E点在 x 轴正坐标上,则这两点的坐标如下
var xO = 0
var yO = 0
var xE = 20
var yE = 0
// 箭头两个角的点:a, b
/**
* ∧
* a/__\ b
* ||
* ||
*/
var xArrowAngle_1 = xE - 5
var yArrowAngle_1 = yE + 3
var xArrowAngle_2 = xE - 5
var yArrowAngle_2 = yE - 3
// 设线段为直角三角形的斜边,则两条直角边长度为
var xLength = Math.abs(x1 - x2)
var yLength = Math.abs(y1 - y2)
// console.log("边长", xLength, yLength);
// 判断线段方向【注意,在此处坐标系为屏幕坐标系,Y 轴应与普通平面坐标系反向,即从上到下为正向】
// 计算线段与 x 轴的夹角三角函数
var cosAngle = yLength / ABLength
var sinAngle = xLength / ABLength
if (x1 < x2 && y1 < y2) {
// 左上到右下 ↘
sinAngle = -sinAngle
} else if (x1 > x2 && y1 > y2) {
// 右下到左上 ↖
sinAngle = -sinAngle
} else if (x1 < x2 && y1 > y2) {
// 左下到右上 ↗
} else if (x1 > x2 && y1 < y2) {
// 右上到左下 ↙
}
// console.log("三角", cosAngle, sinAngle);
// 将 OE 进行旋转得到 OF
var xF = xE * cosAngle - yE * sinAngle
var yF = xE * sinAngle + yE * cosAngle
// 旋转箭头的两个角
var xArrowAngle_1_B = xArrowAngle_1 * cosAngle - yArrowAngle_1 * sinAngle
var yArrowAngle_1_B = xArrowAngle_1 * sinAngle + yArrowAngle_1 * cosAngle
var xArrowAngle_2_B = xArrowAngle_2 * cosAngle - yArrowAngle_2 * sinAngle
var yArrowAngle_2_B = xArrowAngle_2 * sinAngle + yArrowAngle_2 * cosAngle
// console.log("旋转", xO, yO, xF, yF);
// 将 OF 平移至线段中心点,且 O 点与中心点重合,则新的线段坐标如下
xO = center_x1
yO = center_y1
xF = center_x1 + xF
yF = center_y1 + yF
// console.log("move OE", xO, yO, xF, yF);
// 平移箭头的两个角
xArrowAngle_1_B = center_x1 + xArrowAngle_1_B
yArrowAngle_1_B = center_y1 + yArrowAngle_1_B
xArrowAngle_2_B = center_x1 + xArrowAngle_2_B
yArrowAngle_2_B = center_y1 + yArrowAngle_2_B
if (shape.around === 'double') {
// 双向画线,先画第一侧
ctx.moveTo(xO, yO)
ctx.lineTo(xF, yF)
ctx.lineTo(xArrowAngle_1_B, yArrowAngle_1_B)
ctx.lineTo(xArrowAngle_2_B, yArrowAngle_2_B)
ctx.lineTo(xF, yF)
}
// 计算 F 点在线段的哪一侧,是否和光标点击点位于同一侧,或者双向画箭头
var vectorF = (x1 - xF) * (y2 - yF) - (y1 - yF) * (x2 - xF)
// if ((vector > 0 && vectorF < 0) || (vector < 0 && vectorF > 0) || shape.around == "double") {
if ((shape.site === 'right' && vectorF < 0) ||
(shape.site === 'left' && vectorF > 0) ||
shape.around === 'double') {
// 不同侧,旋转Angle之后再旋转180°
xF = xE * cosAngle - yE * sinAngle
yF = xE * sinAngle + yE * cosAngle
// 因为 sin(180) = 0; cos(180) = -1; 所以此处直接简写
xF = -xF
yF = -yF
xF = center_x1 + xF
yF = center_y1 + yF
// 旋转箭头的两个角
xArrowAngle_1_B = xArrowAngle_1 * cosAngle - yArrowAngle_1 * sinAngle
yArrowAngle_1_B = xArrowAngle_1 * sinAngle + yArrowAngle_1 * cosAngle
xArrowAngle_2_B = xArrowAngle_2 * cosAngle - yArrowAngle_2 * sinAngle
yArrowAngle_2_B = xArrowAngle_2 * sinAngle + yArrowAngle_2 * cosAngle
xArrowAngle_1_B = center_x1 - xArrowAngle_1_B
yArrowAngle_1_B = center_y1 - yArrowAngle_1_B
xArrowAngle_2_B = center_x1 - xArrowAngle_2_B
yArrowAngle_2_B = center_y1 - yArrowAngle_2_B
}
// 画线
ctx.moveTo(xO, yO)
ctx.lineTo(xF, yF)
ctx.lineTo(xArrowAngle_1_B, yArrowAngle_1_B)
ctx.lineTo(xArrowAngle_2_B, yArrowAngle_2_B)
ctx.lineTo(xF, yF)
}
})
matlab 画中垂线,zrender 绘制带有中垂线的线段相关推荐
- 使用matlab和GMT联合绘制带有省界的中国地图
使用matlab和GMT联合绘制带有省界的中国地图 1下载省级边界数据,地址:http://nfgis.nsdi.gov.cn/nfgis/chinese/c_xz.htm 网站存储有多级边界数据以及 ...
- matlab 画渐近线,如何绘制渐近线?
我遵循了一个小教程,它让我接近了我想要的地方,但它并不完全在那里,我不知道如何用它进行下一步. 以下是我目前的数据: 但我不知道如何在这个图中绘制渐近线.在 我在想我需要创建一个名为Y的变量,它是一条 ...
- matlab画凸轮廓线,凸轮廓线绘制,layout of cam profile,音标,读音,翻译,英文例句,英语词典...
补充资料:地下轮廓线 地下轮廓线 underground outline 暇挡包坏及排拘图t的 卿水吵地砂廓豁黔擎纂鬓豁燕!廓不许平均坡降值为工必亡'则要大 L一C式中L为渗径长度朴万为上下游最大水头 ...
- Matlab绘制带有填充区域的曲线
Matlab绘制带有填充区域的曲线 https://zhuanlan.zhihu.com/p/435763835 效果如图所示: clear;clc; syms t n = 50; x = linsp ...
- matlab绘图z=sin(x_「matlab画三维图」Matlab 应用之绘制三维图形(基础篇) - seo实验室...
matlab画三维图 在Matlab中,三维图形的绘制包括三维曲线,三维网线图和三维曲面图.闲话不多说,直接进入正题.首先介绍几个函数: 1.plot3(x,y,z,-) 其中,x,y,z为维数相同的 ...
- matlab画三维图电磁场,利用matlab实现矩形波导电磁场分布图的绘制.doc
利用matlab实现矩形波导电磁场分布图的绘制.doc 利用MATLAB实现矩形波导电磁场分布图的绘制(附源程序)通过MATLAB计算并绘出任意时刻金属矩形波导的主模TE10模的电磁场分布图.波导尺寸 ...
- matlab导数曲线怎样画,matlab三次样条曲线的绘制(spline和csape函数详解)
matlab三次样条函数的绘制(spline和csape函数详解) 样条函数是工程中常用的插值函数.早期工程师制图时,把富有弹性的细长木条(所谓样条)用压铁固定在样点上,在其他地方让它自由弯曲,然后沿 ...
- matlab 画 矩阵点,在MATLAB中绘制矩阵中点之间的线
3 个答案: 答案 0 :(得分:1) 这适用于我的数据结构: data = [ 0, 0, 1, 0;... 1, 0, 1, 1;... 1, 1, 0, 1;... 0, 1, 0, 0 ... ...
- matlab极坐标画椭圆,Matlab极坐标曲线怎么绘制
摘要 腾兴网为您分享:Matlab极坐标曲线怎么绘制,桌面时钟,易订货,微拍,玩客云等软件知识,以及天天气象,华图教育app,金立手机软件商店,h5编程软件,充点卷,绘声绘色软件,实达bp690kii ...
最新文章
- 斯蒂文斯理工学院计算机博士,美国斯蒂文斯理工大学——招收全奖土木工程博士生 - 导师招生 - 小木虫 - 学术 科研 互动社区...
- 如何缩短IDEA行号的距离
- linux系统数据落盘之细节
- 1030. 完美数列(25)
- 超级计算机游戏电脑,Salad邀请PC玩家参与全球最大分布式超级计算机的构建
- python字典遍历 没有顺序_Python中字典的顺序问题(为什么实践发现字典的遍历和方法popitem并不是随机的?)...
- 2021.08.23学习内容Pytorch与Torch的关系以及Torchvision作用
- SIP对话、事务详解
- Java内嵌Groovy脚本引擎进行业务规则剥离(一)
- 2022依旧可用的抖音无水印解析工具,免费分享
- 电路基础-6(电容、电感、一阶电路)
- 各种API以及事件初识——笔记
- 个人信息提取(字符串)
- 重庆市企业数据名录爬取采集-信用中国(重庆)
- [PCB]PCB光板生产过程中板子弯曲或翘起原因分析
- 【Demo】银行主数据的修改
- 特权同学海量fpga入门进阶资料教程
- java自行车内走线,科普向 公路车有几种全内走线方式?
- leetcode2248. 多个数组求交集【290场周赛】(java)
- Message的用法
热门文章
- GP61-4-A比例电磁铁配套放大器RT-PSDM2
- 兴义市计算机学校图片,兴义市盘江路小学:“电子白板”让课堂告别“粉笔时代”...
- C语言中的a++与++a的速记理解
- Visual Studio2017源码编译libzip源码
- kinlde笔记导出+想法|有手就行|20行代码python小程序
- php调研方法,你以为调研会拍照就够了?调研图片处理大揭秘 | ?php echo C('PX
- 郭大侠与Rabi-Ribi
- CDOJ 1284 苦恼的郭大侠 map启发式合并
- User agent switcher插件百度云盘不用百度云管家下载大文件
- 计算机硬件故障常用检查方法,电脑硬件故障常用检查办法