Php 从圆心开始在圆的某些扇区中定位点

Php 从圆心开始在圆的某些扇区中定位点,php,javascript,geometry,positioning,Php,Javascript,Geometry,Positioning,问题是从圆心开始在圆的某些扇区中定位点 $dot[1] = secto12; $dot[2] = secto6; $dot[3] = secto8; $dot[4] = secto2; $dot[5] = secto8; $dot[6] = secto3; etc... $dot[1]=第12节; $dot[2]=第6节; $dot[3]=第8节; $dot[4]=secto2; $dot[5]=第8节; $dot[6]=第3节; 等 我们可以使用PHP或javascript 我可以想象一个函

问题是从圆心开始在圆的某些扇区中定位点

$dot[1] = secto12; $dot[2] = secto6; $dot[3] = secto8; $dot[4] = secto2; $dot[5] = secto8; $dot[6] = secto3; etc... $dot[1]=第12节; $dot[2]=第6节; $dot[3]=第8节; $dot[4]=secto2; $dot[5]=第8节; $dot[6]=第3节; 等

我们可以使用PHP或javascript

我可以想象一个函数来模拟向心力。或者是解析几何的一些程序。或者别的什么

任何想法都欢迎。
THX。-

这有两部分:定位点的数学和显示圆+点的渲染引擎

前半部分是一个有趣的数学难题,可能超出了一个简单的堆栈溢出问题的范围。但是一旦你建立了一个渲染系统,你可以很容易地进行实验,直到你达到你想要的


对于下半部分,我建议研究一个Javascript库,以便使用SVG轻松绘制形状和其他矢量图形。

查找点的位置是一个棘手的问题,但我认为我应该这样做(通过实验来支持直觉):

  • 在所需箱子内随机选取一个起始θ。这是点在“顶部”(圆的边缘)的位置。
  • 对于已经在箱子中的每个点,确定其到所选坠落线的(角度)距离。然后用简单的几何学来确定落点将首先遇到的点,以及发生这种情况时落点的位置。这足够放雪花了。
  • 弹珠可以滑动;看看固定点的相邻点,落点接触的一侧。我们可以确定滑动点将首先遇到的邻居。注意墙壁。(我们不会担心弹跳、移动固定点或空降——sim卡不必那么好。)
  • 如果滑动点与另一侧的相邻点接触,则滑动点停止。如果它在同一侧接触,它现在可以沿着邻居自由滑动——我们必须重复上一步。
    顺便说一句,这将提供一个很好的包装,这可能是你所需要的。很难找到最佳的布局。

    构造一个物理引擎来模拟圆圈和墙壁,虽然可能比你希望的要复杂,但并不十分困难。如果您使用Verlet集成来控制球的位置和速度,球之间以及球与管段壁之间的碰撞将变得非常容易解决-您只需将违规球移动到解决碰撞所需的最小距离即可。碰撞响应-速度损失等,隐式处理

    您已经设置了系统,使球被吸引到圆的中心,并被限制停留:

  • 离中心有一段距离
  • 在他们的领域内
  • 与其他球保持一定距离
  • 一个简单的物理模拟将为球提供一个良好的包装,你将免费获得一个看起来很酷的动画


    这是对该方法的一个很好的解释(直到“刚体”部分的所有内容都是合适的)

    使用sfc或希尔伯特曲线或格雷码来解决这一问题非常简单。实际上,希尔伯特曲线是图的哈密顿遍历,这样就产生了一个格雷码。你可以在网上搜索有关格雷码的信息,以及它如何用于正确定义硬盘上的扇区。如果使用希尔伯特曲线来解决问题,其约束条件是圆必须覆盖2次幂的平面。另一个问题是,这只是一种近似方法,但却是一种非常好的方法。

    我使用的解决方案有点复杂。而且不是通用的。我们需要手动计算某些东西($factor(角度的变化)和$dots(在特定半径上绘制的点数))

    但我想给其他需要类似东西的人一些基本想法:

    1-我们使用方程找到给定的点:
    0.-a中心点:($x0,$y0)
    1.-a半径:$r
    2.-角度:$angle

    $x = floor($x0 + $r * sin($angle * pi() / 180));
    $y = floor($y0 + $r * -cos($angle * pi() / 180));
    
    2-我们绘制点(一定数量的点),改变半径和角度
    点的数量取决于半径的大小。半径越大,点越多。我们需要定义一个函数来逐扇区绘制点

    3-我们需要手动计算某些东西($factor(角度变化)和$dots(在特定半径上绘制的点数))。这是:

    if ($r >= 90) {
        $dots = 4;
        $factor = 12.1;
    }
    if ($r >= 100) {
        $dots = 4;
        $factor = 12.4;
    }
    if ($r >= 110) {
        $dots = 5;
        $factor = 8.4;
    }
    if ($r >= 120) {
        $dots = 6;
        $factor = 6.2;
    }
    if ($r >= 130) {
        $dots = 7;
        $factor = 5.2;
    }
    if ($r >= 140) {
        $dots = 8;
        $factor = 4.4;
    }
    if ($r >= 150) {
        $dots = 9;
        $factor = 3.8;
    }
    if ($r >= 200) {
        $dots = 10;
        $factor = 3.40;
    }
    if ($r >= 220) {
        $dots = 11;
        $factor = 3.0;
    }
    
    这些就是解决这个问题的主要思路,用这种巧妙的方式

    4-显然,这段代码(在函数中)必须在嵌套循环中调用(在我的例子中是3)

    $start是与起始图形的角度:0、30、60、…、330

    好的,下面是函数。享受:

    function plot($sector, $start) {
    
        static $static;
        $x0 = 0;
        $y0 = 0;
    
        if ( ! isset($static[$sector])) {
            /*
             * factor: related to the amplitude of the arc on which dots are drawn. (11.1 -> 3.0)
             * dots: how many dots draw towards the right. (3 -> 10)
             * r: radius in pixels. (60 -> 240)
             * jstatic: save last position of dot drawn.
             *
             */
            $static[$sector]['factor'] = 11.1;
            $static[$sector]['dots'] = 4;
            $static[$sector]['r'] = 60;
            $static[$sector]['jstatic'] = 0;
        }
    
        $factor = $static[$sector]['factor'];
        $dots = $static[$sector]['dots'];
        $r = $static[$sector]['r'];
        $jstatic = $static[$sector]['jstatic'];
    
        for ($j = $jstatic; $j < $dots; $j ++ ) {
            if ($r >= 90) {
                $dots = 4;
                $factor = 12.1;
            }
            if ($r >= 100) {
                $dots = 4;
                $factor = 12.4;
            }
            if ($r >= 110) {
                $dots = 5;
                $factor = 8.4;
            }
            if ($r >= 120) {
                $dots = 6;
                $factor = 6.2;
            }
            if ($r >= 130) {
                $dots = 7;
                $factor = 5.2;
            }
            if ($r >= 140) {
                $dots = 8;
                $factor = 4.4;
            }
            if ($r >= 150) {
                $dots = 9;
                $factor = 3.8;
            }
            if ($r >= 200) {
                $dots = 10;
                $factor = 3.40;
            }
            if ($r >= 220) {
                $dots = 11;
                $factor = 3.0;
            }
    
            if ($j == $dots - 1) {
                $j = 0;
                $jstatic = 0;
                // increase radius (by 10 pixels --each dot have 7 pixel of diameter) to the next arc.
                $r = $r + 10;
            }
    
            // stop if circumference is reached.
            if ($r > 240)
                break;
    
            $angle = $factor * $j + $start;
    
            // (x, y) is...
            $x = floor($x0 + $r * sin($angle * pi() / 180));
            $y = floor($y0 + $r * -cos($angle * pi() / 180));
    
            $pos['x'] = $x;
            $pos['y'] = $y;
    
            $jstatic ++;
    
            // save all dat by each sector
            $static[$sector]['factor'] = $factor;
            $static[$sector]['dots'] = $dots;
            $static[$sector]['r'] = $r;
            $static[$sector]['jstatic'] = $jstatic;
    
            /*
             * only for debugging:
             * counting how many dots are drawn
              static $countDots = 0;
              global $countDots;
              $countDots++;
             */
            return $pos;
        }
    }
    
    功能图($sector,$start){
    静态$static;
    $x0=0;
    $y0=0;
    如果(!isset($static[$sector])){
    /*
    *系数:与绘制点的弧的振幅有关。(11.1->3.0)
    *点:向右画多少点。(3->10)
    *r:以像素为单位的半径。(60->240)
    *jstatic:保存绘制的点的最后位置。
    *
    */
    $static[$sector]['factor']=11.1;
    $static[$sector]['dots']=4;
    $static[$sector]['r']=60;
    $static[$sector]['jstatic']=0;
    }
    $factor=$static[$sector]['factor'];
    $dots=$static[$sector]['dots'];
    $r=$static[$sector]['r'];
    $jstatic=$static[$sector]['jstatic'];
    对于($j=$jstatic;$j<$dots;$j++){
    如果($r>=90){
    $dots=4;
    $factor=12.1;
    }
    如果($r>=100){
    $dots=4;
    $factor=12.4;
    }
    如果($r>=110){
    $dots=5;
    $factor=8.4;
    }
    如果($r>=120){
    $dots=6;
    $factor=6.2;
    }
    如果($r>=130){
    $dots=7;
    $factor=5.2;
    }
    如果($r>=1
    
    function plot($sector, $start) {
    
        static $static;
        $x0 = 0;
        $y0 = 0;
    
        if ( ! isset($static[$sector])) {
            /*
             * factor: related to the amplitude of the arc on which dots are drawn. (11.1 -> 3.0)
             * dots: how many dots draw towards the right. (3 -> 10)
             * r: radius in pixels. (60 -> 240)
             * jstatic: save last position of dot drawn.
             *
             */
            $static[$sector]['factor'] = 11.1;
            $static[$sector]['dots'] = 4;
            $static[$sector]['r'] = 60;
            $static[$sector]['jstatic'] = 0;
        }
    
        $factor = $static[$sector]['factor'];
        $dots = $static[$sector]['dots'];
        $r = $static[$sector]['r'];
        $jstatic = $static[$sector]['jstatic'];
    
        for ($j = $jstatic; $j < $dots; $j ++ ) {
            if ($r >= 90) {
                $dots = 4;
                $factor = 12.1;
            }
            if ($r >= 100) {
                $dots = 4;
                $factor = 12.4;
            }
            if ($r >= 110) {
                $dots = 5;
                $factor = 8.4;
            }
            if ($r >= 120) {
                $dots = 6;
                $factor = 6.2;
            }
            if ($r >= 130) {
                $dots = 7;
                $factor = 5.2;
            }
            if ($r >= 140) {
                $dots = 8;
                $factor = 4.4;
            }
            if ($r >= 150) {
                $dots = 9;
                $factor = 3.8;
            }
            if ($r >= 200) {
                $dots = 10;
                $factor = 3.40;
            }
            if ($r >= 220) {
                $dots = 11;
                $factor = 3.0;
            }
    
            if ($j == $dots - 1) {
                $j = 0;
                $jstatic = 0;
                // increase radius (by 10 pixels --each dot have 7 pixel of diameter) to the next arc.
                $r = $r + 10;
            }
    
            // stop if circumference is reached.
            if ($r > 240)
                break;
    
            $angle = $factor * $j + $start;
    
            // (x, y) is...
            $x = floor($x0 + $r * sin($angle * pi() / 180));
            $y = floor($y0 + $r * -cos($angle * pi() / 180));
    
            $pos['x'] = $x;
            $pos['y'] = $y;
    
            $jstatic ++;
    
            // save all dat by each sector
            $static[$sector]['factor'] = $factor;
            $static[$sector]['dots'] = $dots;
            $static[$sector]['r'] = $r;
            $static[$sector]['jstatic'] = $jstatic;
    
            /*
             * only for debugging:
             * counting how many dots are drawn
              static $countDots = 0;
              global $countDots;
              $countDots++;
             */
            return $pos;
        }
    }