马黑黑 发表于 2023-12-25 20:57

小球按圆弧布排的实现演示

本帖最后由 马黑黑 于 2023-12-25 21:22 编辑

先看正弦、余弦计算函数:

正弦 : sin(radian) -> 返回 -1.0 ~ 1.0
余弦 : cos(radian) -> 返回 -1.0 ~ 1.0

上式,radian 为弧度。角度(angle)换算为弧度的公式 :

      radian = 2 * PI / 360 * angle

      可简化为 :

      radian = PI / 180 * angle

求圆周上任意一点坐标值,圆心是重要参照。相交于圆心 o 的水平线和垂直线是我们熟知的坐标系,从 o 出发的任意一条直线会与圆周相交,我们要求的就是该相交点的坐标值。该直线与水平线的夹角是计算圆周点坐标的依据之一,计算依据还有半径 r,公式为:

      x = r + r * cos(radian)
      y = r + r * sin(randian)

以上公式,用 JS 表达:

      x = r + r * Math.cos(radian)
      y = r + r * Math.sin(radian)

同样的,角度转弧度公式的 JS 表达法为:

      radian = Math.PI / 180 * angle

就是说,JS 的数学方法中,π(PI) 表示为 Math.PI,sin 表示为 Math.sin(弧度),cos 表示为 Math.cos(弧度)。

下面给一个例子:经过圆心 o 的直线与圆周相交于某点,已知半径和夹角,求相交点的坐标——

let angle = 60, r = 200;
let radian = Math.PI / 180 * angle;
let x = r + r * Math.cos(radian),
      y = r + r * Math.sin(radian);

console.log(x,y);

最后再给一个HTML实例:400*400的圆形父元素内有两个40*40的圆形子元素,绿色小球留在它的默认位置,红色小球根据上述圆周点坐标计算机制脱离了默认位置,其圆心与圆周上的某一点相交。需要注意的是,XY坐标点要减去小球的半径,小球圆心才会与圆周上的指定点相重合。代码如下:

<style>
#mydiv {
      width: 400px;
      height: 400px;
      border: 1px solid gray;
      border-radius: 50%;
      position: relative;
}
.ball {
      position: absolute;
      width: 40px;
      height: 40px;
      border-radius: 50%;
      background: red;      
}
</style>

<div id="mydiv">
      <div class="ball"></div>
      <div class="ball" style="background:green"></div>
</div>

<script>

let angle = 60, r = 200;
let radian = Math.PI / 180 * angle;
let x = r + r * Math.cos(radian),
      y = r + r * Math.sin(radian);

let ball = document.querySelector('.ball');

ball.style.left = x - 20 + 'px';
ball.style.top = y - 20 + 'px';

</script>

以上 HTML 实例代码,可以到这里运行:pencil code (52qingyin.cn)

红影 发表于 2023-12-25 21:30

这个看迷糊了,圆周上的点就是r * cos(radian)和r * Math.sin(radian)啊,为什么还要加r ?

红影 发表于 2023-12-25 21:40

去试了,红色小球落在了圆周上,绿色的跑出去了{:4_203:}

红影 发表于 2023-12-25 21:47

我去掉+r后,红色小球跑到奇怪的位置上了,绿色小球仍然在原地。彻底看迷糊了{:4_173:}

红影 发表于 2023-12-25 22:08

加上r是因为小球原本不在中心的原因么,加上是把它挪到中心去吧。嗯,红色的小球明白了。
之前的的帖子里做动画时已经把它先弄到中心了,所以不用加。

绿色的小球又是怎么回事,怎么跑到对角方向去了?

马黑黑 发表于 2023-12-25 22:29

红影 发表于 2023-12-25 21:30
这个看迷糊了,圆周上的点就是r * cos(radian)和r * Math.sin(radian)啊,为什么还要加r ?

数学公式如此: 半径 +半径 * cos(弧度) 、半径 +半径 * sin(弧度)

不加半径,到达不了圆周上的点

在 HTML 实体环境中,若绝对定位的子元素不加 r,也到达不了圆周点。我的一些帖子没有加 r,原因在于我把子元素定位在了圆心,它们已经事实上加 r 了。

马黑黑 发表于 2023-12-25 22:30

红影 发表于 2023-12-25 22:08
加上r是因为小球原本不在中心的原因么,加上是把它挪到中心去吧。嗯,红色的小球明白了。
之前的的帖子里 ...

父元素如果是矩形的,你就能明白为什么

马黑黑 发表于 2023-12-25 22:31

红影 发表于 2023-12-25 21:40
去试了,红色小球落在了圆周上,绿色的跑出去了

绿色小球不是跑出去,它待在原本的位置:left和top在父元素的左上角

红影 发表于 2023-12-25 22:39

马黑黑 发表于 2023-12-25 22:29
数学公式如此: 半径 +半径 * cos(弧度) 、半径 +半径 * sin(弧度)

不加半径,到达不了圆周上的点


是的,我后来想明白了。开始有点懵,就是习惯了前面那些已经定位的帖子了{:4_173:}

红影 发表于 2023-12-25 22:41

马黑黑 发表于 2023-12-25 22:30
父元素如果是矩形的,你就能明白为什么

是正方形的也要加一半烦长宽,总之需要把它挪到中心去。

红影 发表于 2023-12-25 22:43

马黑黑 发表于 2023-12-25 22:31
绿色小球不是跑出去,它待在原本的位置:left和top在父元素的左上角

但是x是算出来的,在红色的位置上减的啊{:4_203:}

马黑黑 发表于 2023-12-25 22:47

本帖最后由 马黑黑 于 2023-12-25 22:56 编辑

红影 发表于 2023-12-25 22:43
但是x是算出来的,在红色的位置上减的啊
这是两码事额。

计算圆周上某一点的坐标,和驱使小球去到那个点,是两个事情。

红色小球原本的点和绿色小球现在的点一样,默认在矩形(父元素)的左上角。然后,我们计算了夹角为 60 度的圆周上的那个点坐标,并驱使红色小球去到那个点。

马黑黑 发表于 2023-12-25 22:49

红影 发表于 2023-12-25 22:41
是正方形的也要加一半烦长宽,总之需要把它挪到中心去。

不用把问题复杂化。你只要知道如何计算圆周上某一个点的坐标值,然后把这个坐标值赋予元素的left和top就行了。

马黑黑 发表于 2023-12-25 22:51

红影 发表于 2023-12-25 22:39
是的,我后来想明白了。开始有点懵,就是习惯了前面那些已经定位的帖子了

你主要是没有分清计算与驱动。计算方法是按照数学原理来的,驱动是在得到坐标值后将值赋予子元素的left和top对它进行定位。

定位方式不止left和top,我们还可以用 transform 的 translate方式,将子元素从某和位置移动到从另一个位置。等等。

红影 发表于 2023-12-25 23:03

马黑黑 发表于 2023-12-25 22:47
这是两码事额。

计算圆周上某一点的坐标,和驱使小球去到那个点,是两个事情。


let x = r + r * Math.cos(radian),这个值算出来是300
然后ball.style.left = x - 20 + 'px';这个是绿色小球的左边值吧,我就是没看懂这个值是怎么回事

红影 发表于 2023-12-25 23:08

马黑黑 发表于 2023-12-25 22:30
父元素如果是矩形的,你就能明白为什么

我收回15楼的回复,再看一遍,知道了,所有的js都是给红球的,我弄错了,和绿球完全无关。
现在总算弄明白了,前面全错了{:4_189:}

红影 发表于 2023-12-25 23:10

马黑黑 发表于 2023-12-25 22:51
你主要是没有分清计算与驱动。计算方法是按照数学原理来的,驱动是在得到坐标值后将值赋予子元素的left和 ...

知道了知道了,我前面弄错了,还以为给了xy就完成红球了,实际还要给它定位。我前面一直以为定位是给绿球的,哈哈,错得离谱。行了,现在没问题了{:4_196:}

马黑黑 发表于 2023-12-25 23:13

红影 发表于 2023-12-25 23:08
我收回15楼的回复,再看一遍,知道了,所有的js都是给红球的,我弄错了,和绿球完全无关。
现在总算弄明 ...

JS获取的小球,

    let ball = document.querySelector('.ball');

它拿到的是第一个出现的小球。要拿全部的小球这样做:

    let ball = document.querySelectorAll('.ball');

然后,用数组下标一一操作这些小球,比如操作第二个、让它改变背景色为粉红:

    ball.style.background = 'pink';

马黑黑 发表于 2023-12-25 23:15

红影 发表于 2023-12-25 23:03
let x = r + r * Math.cos(radian),这个值算出来是300
然后ball.style.left = x - 20 + 'px';这个是绿色 ...

这个我有说明的:减去的 20 是小球自己的半径,这样小球的圆心就和计算出来的点重合

马黑黑 发表于 2023-12-25 23:17

红影 发表于 2023-12-25 23:10
知道了知道了,我前面弄错了,还以为给了xy就完成红球了,实际还要给它定位。我前面一直以为定位是给绿球 ...

文科生的样纸
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 小球按圆弧布排的实现演示