Javascript 沿弧移动一点,距离另一点

Javascript 沿弧移动一点,距离另一点,javascript,math,canvas,trigonometry,Javascript,Math,Canvas,Trigonometry,我有一个180度的弧度。我有两个点(V3和V4)沿弧长绘制。如何将V4的位置设置为相对于其与V3(而不是V1)的距离?我不想使用角度距离,而是x&y中的距离。我仍然希望V4沿着同一条弧移动,但我希望能够拖动一个滑块,根据V3的位置,正值朝着V2移动,负值朝着V1移动 任何帮助都会很棒。谢谢大家! var canvas=document.getElementById(“canvas”); var ctx=canvas.getContext(“2d”); var percentSlider=doc

我有一个180度的弧度。我有两个点(V3和V4)沿弧长绘制。如何将V4的位置设置为相对于其与V3(而不是V1)的距离?我不想使用角度距离,而是x&y中的距离。我仍然希望V4沿着同一条弧移动,但我希望能够拖动一个滑块,根据V3的位置,正值朝着V2移动,负值朝着V1移动

任何帮助都会很棒。谢谢大家!

var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var percentSlider=document.getElementById(“percentSlider”);
var distanceSlider=document.getElementById(“distanceSlider”);
var pReadout=document.querySelector(“.readout.percent”);
var dReadout=document.querySelector(“.readout.distance”);
var distance=document.getElementById(“距离”);
类向量{
构造函数(x,y){
这个.x=x;
这个。y=y;
}
}
函数drawDot(v、txt、颜色){
ctx.beginPath();
r=4;
ctx.arc(v.x,v.y,r,0,Math.PI*2,false);
ctx.closePath();
ctx.fillStyle=颜色;
ctx.fill();
ctx.font='10px无衬线';
ctx.fillText(txt,v.x-6,v.y-12);
}
功能钳位(n、minn、maxn){
返回Math.max(Math.min(maxn,n),minn);
}
函数PosByPercent(cx、cy、d、半径、perc){
角度=perc*Math.PI;
设newX=cx+半径*Math.cos(角度);
设newY=cy-半径*Math.sin(角度);
返回新向量(newX,newY)
}
函数PosByDistance(cx、cy、d、半径){
a=1——数学功率(d/半径,2)/2;
a=夹具(a,-1,1);
角度=数学acos(a);
设newX=cx+半径*Math.cos(角度);
设newY=cy-半径*Math.sin(角度);
返回新向量(newX,newY)
}
函数drawAll(){
clearRect(0,0,canvas.width,canvas.height);
设角度=0;
设d=距离滑块.value;
设p=percentSlider.value;
设cx=canvas.width/2;
设cy=canvas.height/2;
设半径=70;
v1=新矢量(cx+半径,cy);
v2=新矢量(cx-半径,cy);
v3=百分比(cx,cy,d,半径,p);
v4=波旁距离(cx,cy,d,半径,p);
ctx.beginPath();
ctx.弧(cx,cy,半径,数学PI,0,假);
ctx.lineWidth=3;
ctx.strokeStyle=“#3f3f”;
ctx.stroke();
drawDot(v1,“v1”,“#40e4ff”);
drawDot(v2,“v2”,“#40e4ff”);
drawDot(v3,“v3”和“FF0000”);
drawDot(v4,“v4”,“00ff48”);
}
函数getDistances(){
设a=v4.x-v3.x;
设b=v4.y-v3.y;
设c=Math.sqrt(a*a+b*b);
distance.innerHTML=“dist-v3&v4:+parseFloat(c).toFixed(1)+”;
}
变量v1、v2、v3、v4;
drawAll();
getdistance();
dReadout.innerHTML=distanceSlider.value;
pReadout.innerHTML=percentSlider.value;
percentSlider.oninput=函数(){
pReadout.innerHTML=percentSlider.value;
drawAll();
getdistance();
}
distanceSlider.oninput=函数(){
dReadout.innerHTML=distanceSlider.value;
drawAll();
getdistance();
}
正文{
边际:0px;
字体系列:无衬线;
显示器:flex;
弯曲方向:立柱;
证明内容:中心;
对齐项目:居中;
}
#帆布{
背景色:#2b2b;
边框:1px实心rgba(0,0,0,0.2);
宽度:200px;
高度:200px;
利润底部:4倍;
}
#控制{
背景色:白色;
位置:固定;
排名:0;
右:0;
填充:10px;
宽度:200px;
框大小:边框框;
}
.行{
显示:块;
}
标签{
显示:块;
文本对齐:左对齐;
}
标签跨度{
字体大小:10px;
}
.读数{
宽度:80px;
字体大小:12px;
文本对齐:左对齐;
左侧填充:2px;
框大小:边框框;
}
#myRange{
宽度:130px;
}
#距离{
字体大小:13px;
位置:固定;
显示器:flex;
弯曲方向:立柱;
证明内容:中心;
调整项目:灵活启动;
文本对齐:左对齐;
排名:0;
左:0;
背景:#333;
颜色:白色;
填充:10px;
}
#距离跨度{
颜色:rgba(255,255,255,0.6);
}

V3(%)
V4(与V1的距离)

当您计算
v3
位置时,您知道其
角度作为中间结果

记住此角度并将其用于计算
v4
位置,如下所示:

function PosByDistanceFromV3(cx, cy, d, radius, v3angle) {
  a = 1 - Math.pow(d / radius, 2) / 2;
  a = clamp(a, -1, 1);
  angle = Math.acos(a) + v3angle;
  angle = clamp(angle, 0, Math.PI);
  let newX = cx + radius * Math.cos(angle);
  let newY = cy - radius * Math.sin(angle);
  return new Vector(newX, newY)
}

通过使用弧长和半径获得角度,我能够获得正确的位置:

函数PosByDistance(cx、cy、弧长、半径)
{
角度=弧长/半径;
角度=钳制(角度,0,Math.PI);//将点限制为圆弧
newX=cx+半径*数学cos(角度);
newY=cy-半径*数学sin(角度);
返回新向量(newX,newY);
}