贝赛尔曲线

news2024/11/29 10:34:16

在这里插入图片描述

<template>
    <svg width="400" height="400" class="BG" @mousemove="mousemove">
        <!-- 这样拼字符串,少些点加号,方便改一些 -->
        <path class="Line"
            :d="`M${StartPoint[0]} ${StartPoint[1]} S${ControlPoint[0]} ${ControlPoint[1]} ${EndPoint[0]} ${EndPoint[1]}`" />
        <!-- 起始点 -->
        <circle :cx="StartPoint[0]" :cy="StartPoint[1]" r="5" style="fill:pink; stroke:red; stroke-width:2;" />
        <!-- 结束点示意位置 -->
        <circle :cx="EndPoint[0]" :cy="EndPoint[1]" r="5" style="fill:pink; stroke:red; stroke-width:2;" />
        <!-- 控制点示意位置 -->
        <circle :cx="ControlPoint[0]" :cy="ControlPoint[1]" r="5" style="fill:pink; stroke:red; stroke-width:2;" />
    </svg>
</template>
<script setup>
import { nextTick, ref } from 'vue';
const StartPoint = ref([200, 200]);
const EndPoint = ref([400, 200])
const ControlPoint = ref([300, 200])

const ConstantAngle = 45;

// 未优化的计算方法
const ControlPointCompute = () => {
    // 计算起始坐标点 的 弧度值
    const radian = Math.atan2((EndPoint.value[1] - StartPoint.value[1]), (EndPoint.value[0] - StartPoint.value[0]));
    // 用 cos 弧度 来计算 偏移的角度量
    // CosRadian 弧度值为 -1 ~ 0 ~ 1 的值,可以用来进行判断坐标点左侧还是右侧
    const CosRadian = Math.cos(radian);
    // 当前两点之间的角度值
    const Angle = radian * (180 / Math.PI);
    // 控制点与原点的角度值
    const ControlAngle = Angle - (CosRadian * ConstantAngle);
    // 三角函数求 两点之间的距离(也就是斜边长)
    const distance = Math.sqrt(Math.pow(Math.abs(EndPoint.value[0] - StartPoint.value[0]), 2) + Math.pow(Math.abs(EndPoint.value[1] - StartPoint.value[1]), 2));
    // 根据弧度值,计算一个根据距离和角度决定的半径长度来计算控制点
    const distanceByCosRadian = distance / (2 - Math.abs(CosRadian) * (1 - 0.414));
    // 已知夹角,求临边长及对变长,即为二维坐标值
    const X = Math.cos(((2 * Math.PI) / 360) * ControlAngle) * distanceByCosRadian;
    const Y = Math.sin(((2 * Math.PI) / 360) * ControlAngle) * distanceByCosRadian;
    // 加上原点值,就可得出当前控制点的实际坐标值
    ControlPoint.value = [X + 200, Y + 200];
}




// 弧度值转角度值的常量
const R2A = 180 / Math.PI;
// 角度值转弧度值的常量
const A2R = (2 * Math.PI) / 360

// 优化后的计算方法(减少计算为优先)
// 优化原则:1、同样的计算不计算两次(减少计算时间);
//          2、不创建只使用一次的变量(减少创建变量时的内存消耗)
//          3、测试完全部功能再优化(计算优化后的代码基本上是没有可读性的,所以在优化时,尽量先测试)
const TestCompute = (X, Y) => {
    // X轴坐标点差值
    const DX = Y[0] - X[0];
    // Y轴坐标点差值
    const DY = Y[1] - X[1];
    // 鼠标位置与原点的弧度值
    const radian = Math.atan2(DY, DX);
    // 鼠标点与坐标点的 余弦 值
    const CosRadian = Math.cos(radian);
    // 计算控制点与原点的距离
    const dis = Math.sqrt(Math.pow(Math.abs(DX), 2) + Math.pow(Math.abs(DY), 2)) / (2 - Math.abs(CosRadian) * (1 - 0.414));
    // 计算控制点的弧度值
    const ControlRadian = A2R * (radian * R2A - (CosRadian * ConstantAngle));
    // 计算控制点位置
    ControlPoint.value = [Math.cos(ControlRadian) * dis + X[0], Math.sin(ControlRadian) * dis + X[1]];
}

// ControlPointCompute();
TestCompute(StartPoint.value, EndPoint.value);
const mousemove = (e) => {
    // 获取当前鼠标相对父级位置
    const { offsetX, offsetY } = e;
    EndPoint.value[0] = offsetX;
    EndPoint.value[1] = offsetY;
    // ControlPointCompute();
    TestCompute(StartPoint.value, EndPoint.value);
}




</script>
<style lang="less" scoped>
.BG {
    background-color: rgba(255, 255, 255, 0.1);
}

.Line {
    fill: none;
    stroke: red;
    stroke-width: 2;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CNN经典模型之ALexNet、ResNet、DenseNet总结和比较

目录 ALexNet(2012 研究背景 思路和主要过程 网络模型 数据增强 主要贡献点 ResNet(2015 研究背景 思路和主要过程 Residual block(残差块)和shortcut connections(捷径连接) bottleneck block-瓶颈模块 主要贡献点: Denset(2017 研究背景 思路和主要过程 Dense…

mysql忘记密码怎么解决(几乎囊括你可能遇到的所有问题)

mysql忘记密码解决&#xff1a; 多次输入都错误&#xff0c;出现下面的提示 Access denied for user rootlocalhost (using password: YES)解决&#xff1a; 1.关闭mysql service mysqld stop2.mysql停止后输入 mysqld --shared-memory --skip-grant-tables3.重新打开一个…

利用Pinpoint搭建全链路监控系统

随着项目微服务的进行&#xff0c;微服务数量逐渐增加&#xff0c;服务间的调用也越来越复杂&#xff0c;我们急切需要一个APM工具帮我们监控各个服务的性能及对服务间的调用进行跟踪&#xff0c;而通过调研多个开源APM工具后&#xff0c;最终我们选择了Pinpoint。 简介 Pinp…

PyQt5 QDialog对话框(QMessageBox,QInputDialog,QFontDialog,QFileDialog,QColorDialog)

PyQt5 QDialog对话框QDialog类图QDialogQMessageBoxQInputDialogQFontDialogQFileDialogQColorDialogQDialog类图 QDialog import sys from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtCore import Qtclass MyDialogWindow…

数据结构之插入排序

插入排序 一种思想我们所在指向位是需要进行插入的数据 我们锁指向位置前的数据是被插入的数据组 我们根据与前面的数据元素一个个比较来确定插入位置的排序 比如现在的76比前面的97小&#xff0c;97进行一个右移&#xff0c;就是赋值给data[4]&#xff08;我这里猜测是76应该是…

QT 介绍

QT 介绍 Qt是一个跨平台的 C 开发库&#xff0c;主要用来开发图形用户界面&#xff08;Graphical User Interface&#xff0c;GUI&#xff09;程序&#xff0c;当然也可以开发不带界面的命令行&#xff08;Command User Interface&#xff0c;CUI&#xff09;程序。且完全面向对…

项目实战——匹配系统(上)

ps&#xff1a;从这篇文章开始&#xff0c;整个项目最精华&#xff08;困难&#xff09;的部分就要来了&#xff0c;因此这里会把每一个步骤细分&#xff0c;并且说一下自己对于每个步骤的思考和理解&#xff08;博主水平有限&#xff0c;错误在所难免&#xff0c;欢迎指出讨论…

MyBatis-Plus(第一篇开山篇)

MyBatis-Plus&#xff08;第一篇开山篇&#xff09; 目录MyBatis-Plus&#xff08;第一篇开山篇&#xff09;结论&#xff1a;使用mybatis plus步骤1.导包2.整合(修改spring-dao配置文件)3.使用3.1 javaBean3.2 mapper层3.3 service层3.3.1 service接口3.3.2 service实现类3.4 …

【MEF:深度感知增强(细节增强:色彩映增强)】

Multi-exposure image fusion via deep perceptual enhancement &#xff08;基于深度感知增强的多曝光图像融合&#xff09; 多曝光图像融合 (MEF) 是通过将具有不同曝光的多个镜头集成在一起来解决此问题的有效方法&#xff0c;这在本质上是一个增强问题。在融合过程中&…

IDEA最实用的设置

​ 目录 全局设置 全局设置 选择 Configure->settings进入设置界面 1.设置主题 2.设置编码区的字体及大小 3.设置控制台的字体及大小 4.修改编码方式 解决有时我们在导入项目时&#xff0c;代码中的中文注释变成乱码问题。 5.设置按住Ctrl鼠标滚轮改变字体大小 6.设置…

Java基础深化和提高 ---- 函数式编程 Lambda

Lambda表达式介绍 Lambda简介 Lambda 表达式是 JDK8 的一个新特性&#xff0c;可以取代大部分的匿名内 部类&#xff0c;写出更优雅的 Java 代码&#xff0c;尤其在集合的遍历和其他集合操作 中&#xff0c;可以极大地优化代码结构。 在Java语言中&#xff0c;可以为变量赋予一…

计算机网络-传输层(TCP可靠传输(校验,序号,确认,重传),TCP流量控制,TCP拥塞控制(慢开始,拥塞避免)(快重传,快恢复))

文章目录1. TCP可靠传输2. TCP流量控制3. TCP拥塞控制1. TCP可靠传输 网络层&#xff1a;提供尽最大努力交付&#xff0c;不可靠传输。 传输层&#xff1a;使用TCP实现可靠传输 可靠&#xff1a;保证接收方进程从缓存区读出的字节流与发送方发出的字节流是完全一样的。 TCP可…

redis 哨兵

哨兵可以帮助我们解决主从架构中的单点故障问题 哨兵的配置&#xff1a; 新建目录&#xff1a;usr/local/docker/redis/sen/ docker-compose.yml文件如下 version: "3.1" services:redis1:image: daocloud.io/library/redis:5.0.7restart: alwayscontainer_name: …

STL技巧大赏

STL技巧大赏 map insertinsertinsert 不允许有重复的键值的&#xff0c;如果新插入的键值与原有的键值重复则插入无效beginbeginbeginendendendclearclearclear 清除所有countcountcount 某个元素出现次数lower/upperboundlower/upper boundlower/upperbound set 比 mapmapm…

半导体新能源智能装备上位机工业软件设计方案

一、什么是上位机软件 如果说PLC是工业控制的小脑&#xff0c;那么上位机软件就是其大脑。在概念上&#xff0c;控制者和提供服务者是上位机&#xff0c;被控制者和被服务者是下位机&#xff0c;上位机往往是数字信号的处理和命令的下发&#xff0c;下位机往往是模拟量的处理和…

【Linux】初识系统调用进程状态

文章目录1. 什么是系统调用1.1 通过系统调用获取进程标示符通过其他方式查看PIDTopPS使用PID1.2 通过系统调用创建进程-fork初识2. 进程状态看看Linux内核源代码怎么定义查看状态Z(zombie)-僵尸进程僵尸进程危害孤儿进程1. 什么是系统调用 在linux中&#xff0c;系统调用是指操…

[附源码]java毕业设计校园志愿者服务管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Node_exporter主机探针部署

部署需求分析 使用ansible批量部署node-exporter监控客户端 node-exporter解压安装目录为home 添加至Linux服务重新加载&#xff0c;启动模块并设置开机启动 测试环境&#xff08;centos 7——3.10.0-1160.el7.x86_64&#xff09;运行成功 因为部署步骤较少&#xff0c;单个pla…

主从延迟读写不一致解决方案分析

具体业务场景方案分析 问题背景&#xff1a; 虽然强制走写库&#xff0c;避免了主从延迟带来的读库数据不一致问题&#xff0c;但是增加了写库的QPS&#xff0c;带来了巨大压力&#xff0c;所以通过限流来保护db&#xff0c;但这样会降低QPS。 业务上暂时不清楚&#xff0c;所…

[附源码]java毕业设计校园新闻管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…