将点放在从中心开始的圆的某些扇区中

时间:2011-03-01 17:46:17

标签: php javascript geometry positioning

问题是将点放在从中心开始的圆的某些扇区中。

$dot[1] = secto12;
$dot[2] = secto6;
$dot[3] = secto8;
$dot[4] = secto2;
$dot[5] = secto8;
$dot[6] = secto3;
etc...

我们可以使用PHP或javascript。

我可以想象一个模仿向心力的函数。或者也许是分析几何的一些过程。或者其他......

欢迎任何想法。 THX .-

5 个答案:

答案 0 :(得分:1)

这有两个部分:定位点的数学运算,以及渲染引擎显示圆圈+点。

上半部分是一个有趣的数学难题,可能超出了简单的Stack Overflow问题的范围。但是一旦你设置了渲染系统,你就可以轻松地进行实验,直到找到你想要的东西。

对于下半部分,我建议查看Raphael,这是一个Javascript库,可以使用SVG轻松绘制形状和其他矢量图形。

答案 1 :(得分:1)

找到一个点停下来的问题很棘手,但我认为我会采用这种方式(通过实验,支持直觉):

  1. 在所需的bin中随机选择一个起始θ。这是点“顶部”(圆的边缘)的位置。
  2. 对于bin中已有的每个点,确定与所选下降线的距离(角度)。然后是简单的几何形状来确定落点将首先遇到哪个点,以及发生这种情况时落点的位置。这对雪花来说已经足够了。
  3. 弹珠可以滑动;看看静止点的邻居,在落点接触的一侧。我们可以确定滑点首先遇到哪个邻居。看着墙壁。 (我们不会担心弹跳,移动静止点或空中飞行 - 模拟器不一定非常好。)
  4. 如果滑动点与另一侧的邻居接触,它将停止。如果它在同一侧接触,它现在可以自由地沿着邻居滑动 - 我们必须重复上一步。

P.S。这将是一个非常好的包装,这可能是你所需要的。 最佳包装真的很难找到。

答案 2 :(得分:0)

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

你设置了你的系统,使得球被吸引到圆圈的中心,并被限制留下来:

  1. 离中心有一段距离
  2. 在其细分中
  3. 离其他球有一段距离
  4. 简单的物理模拟将为球提供良好的包装,您将获得免费的酷炫动画。

    This是对该方法的一个很好的解释(一切都适用于“刚体”部分是合适的)

答案 3 :(得分:0)

使用sfc或希尔伯特曲线或格雷码解决这个问题非常简单。实际上,希尔伯特曲线是图的哈密尔顿遍历,并且这样生成格雷码。你可以在网上搜索灰色代码以及它如何用于正确定义硬盘上的扇区。如果使用希尔伯特曲线来解决问题,那么它的约束是圆必须覆盖2的幂平面。其他问题是它只是近似但非常好。

答案 4 :(得分:0)

enter image description here

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

但我想为其他需要类似内容的人提供基本思路:

1 .-我们使用找出给定点的等式:
0.-中心点:($ x0,$ y0)
1.-半径:$ 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)

function plot($sector, $start) {
    ....
}

$ 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;
    }
}