可视化基础:已知2点坐标,如何求旋转角度?

博客 分享
0 235
优雅殿下
优雅殿下 2022-07-09 21:01:33
悬赏:0 积分 收藏

可视化基础:已知2点坐标,如何求旋转角度?

问题

已知:fromto 两点的坐标,如何求两点连线的旋转角度?

可以通过余弦定理求解三个角的度数。具体说明如下:

在三角形中,已知边A、B、C, 且A、B、C所对的内角分别是a、b、c, 则:

  • cosa=[B2+C2-A2]/(2BC)
  • cosb=[A2+C2-B2]/(2AC)
  • cosc=[A2+B2-C2]/(2AB)

然后利用反三角函数求角度:

  • a = arccos(cosa)
  • b = arccos(cosb)
  • c = arccos(cosc)

代码实现如下:

// 求角a的度数// 1.求出三角形的三条边const a = to.y - from.yconst b = to.x - from.xconst c = Math.sqrt(a * a + b * b) // 勾股定理 c^2 = a^2 + b^2// 2.求角a的cos值const cosA = (b*b + c*c - a*a)/(2*b*c)// 3.利用反cos求角a的度数let rotate = Math.acos(cosA) * (180 / Math.PI) // 角度 = 弧度 * 180/π// 4.处理正负号to.y < from.y && (rotate = -rotate)

三角函数、反三角函数、角度与弧度互转说明:

const cosv = Math.cos(val)  // val 为弧度值const val = Math.acos(cosv) // 结果 val 为弧度值,没有正负// 角度转弧度:弧度 = 角度 * (π/180)// 弧度转角度:角度 = 弧度 * (180/π)

案例

svg 实现画一条带箭头的边,鼠标hover,边及箭头变色并显示文本。

react 实现如下:

import React, { useState } from 'react'const link = {  from: {    x: 100,    y: 100  },  to: {    x: 300,    y: 50  },}const index = () => {  const [linkHover, setLinkHover] = useState()  const linkMouseEnter = () => {    const { from, to } = link    const a = to.y - from.y    const b = to.x - from.x    const c = Math.sqrt(a * a + b * b)    const cosA = (b*b + c*c - a*a)/(2*b*c) // 求夹角a的角度    let rotate = Math.acos(cosA) * (180 / Math.PI) // 角度 = 弧度 * 180/π    to.y < from.y && (rotate = -rotate)        setLinkHover({      x: (from.x + to.x) / 2,      y: (from.y + to.y) / 2,      rotate,    })  }  const linkMouseLeave = () => {    setLinkHover(undefined)  }  return (    <div>      <svg xmlns="http://www.w3.org/2000/svg" version="1.1">          <g>            <defs>              <marker id="triangle" markerUnits="strokeWidth" markerWidth="5" markerHeight="4" refX="4" refY="2" orient="auto" fill="#67c23a">                <path d="M 0 0 L 5 2 L 0 4 L 1 2 z" />              </marker>              <marker id="triangle-hover" markerUnits="strokeWidth" markerWidth="5" markerHeight="4" refX="4" refY="2" orient="auto" fill="red">                <path d="M 0 0 L 5 2 L 0 4 L 1 2 z" />              </marker>            </defs>            <line x1={link.from.x} y1={link.from.y} x2={link.to.x} y2={link.to.y}              strokeLinecap="round" stroke={linkHover ? 'red' : '#67c23a'} stroke-width="2"              style={{markerEnd: linkHover ? 'url(#triangle-hover)' : 'url(#triangle)'}}            />           {/* 增加 hover 边界,容易操作 */}           <line x1={link.from.x} y1={link.from.y} x2={link.to.x} y2={link.to.y}              stroke="red" stroke-opacity="0.2" stroke-width="12"              onMouseEnter={linkMouseEnter}              onMouseLeave={linkMouseLeave}              style={{cursor: 'pointer'}}           />          </g>          {linkHover ? (            // 42 为文本宽度的一半,8 为文本高度的一半 svg transform="rotate(旋转角度 旋转中心x,旋转中心y)" 默认旋转中心为svg左上角            <text x={linkHover.x - 42} y={linkHover.y - 8} fill="red" transform={`rotate(${linkHover.rotate} ${linkHover.x},${linkHover.y})`}>点击删除连线</text>          ) : null}        </svg>    </div>  )}export default index

未经允许不得转让。

posted @ 2022-07-09 20:25 ESnail 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员