ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-07-09 20:31:24  阅读:195  来源: 互联网

标签:rotate const 弧度 180 已知 角度 可视化 坐标 Math


问题

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

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

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

  • cosa=[B²+C²-A²]/(2BC)
  • cosb=[A²+C²-B²]/(2AC)
  • cosc=[A²+B²-C²]/(2AB)

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

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

代码实现如下:

// 求角a的度数
// 1.求出三角形的三条边
const a = to.y - from.y
const b = to.x - from.x
const 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"
              onm ouseEnter={linkMouseEnter}
              onm ouseLeave={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

未经允许不得转让。

标签:rotate,const,弧度,180,已知,角度,可视化,坐标,Math
来源: https://www.cnblogs.com/EnSnail/p/16461813.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有