绘制极地玫瑰——如何使用“n”和“d”来实现不同的形状?

问题描述 投票:0回答:1

以代码形式,笛卡尔系中极玫瑰点坐标的计算可以表示为:

X := OriginX + A * Cos(K * Theta) * Cos(Theta);
Y := OriginY + A * Cos(K * Theta) * Sin(Theta);
参数 意义
OriginX
玫瑰中心点的
X
坐标
OriginY
玫瑰中心点的
Y
坐标
A
目标玫瑰半径
K
角频率

上面的代码可以完美运行。例如,将

K
设置为
5
,我会得到一朵有五个花瓣的花。对于
K
的其他正整数值,我也得到了正确的花,与维基百科上给出的第一行一致:


图片来源:Jason Davies,来自 Wikimedia Commons

现在我希望我的代码能够从其他行生成玫瑰。我找到了文章极地玫瑰园,里面有一张有各种玫瑰的图片,其中

k
是整数或实数:

https://blog.k2h.se/post/2020-01-03-polar-rose-garden_files/figure-html/unnamed-chunk-2-1.png

例如,对于

k = 1 / 3
,玫瑰应该是这样的:

另外https://blog.k2h.se/post/2020-01-03-polar-rose-garden_files/figure-html/unnamed-chunk-2-1.png查找标题

1/3

但是如果我使用以下代码:

var
  Theta:   Single;
  OriginX: Integer;
  OriginY: Integer;
  Size:    Integer;
  X:       Integer;
  Y:       Integer;
  K:       Single;
begin
  OriginX := 120;
  OriginY := 120;
  Size    := 120;
  K       := 1 / 3;
  Theta   := 0.0;

  while Theta < Pi * 2 do
  begin
    X := Round(OriginX + Size * Cos(K * Theta) * Cos(Theta));
    Y := Round(OriginY + Size * Cos(K * Theta) * Sin(Theta));

    Canvas.Pixels[X, Y] := clGray;

    Theta += 0.001;
  end;
end;

玫瑰看起来像这样:

有人可以告诉我为什么我的图表损坏了吗?

PS:我不是数学家,所以 C/Pascal 代码就完美了。

algorithm math pascal
1个回答
0
投票

我们转向 https://en.wikipedia.org/wiki/Rose_(mathematics)#Roses_with_rational_number_values_for_k 并了解到:

n和d均为奇数时,正弦曲线的正半周期和负半周期是重合的。这些玫瑰花的图形在任意连续的极角区间(长)中完成。

n 为偶数且 d 为奇数时,反之亦然,玫瑰将完全绘制在连续的极角区间2dπ

因此应该进行快速模检查:

<script type="module" src="https://cdnjs.cloudflare.com/ajax/libs/graphics-element/1.11.1/graphics-element.js" integrity="sha512-fz6xdkeMImCEkyHV+HPpg7C9cxoqc0w9RdSzm9ufj2wjFQFz71iJvyazoM9tXRGBzN40GuNY2e5fmimRiBFoJw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/graphics-element/1.11.1/graphics-element.css" integrity="sha512-sD4sJLVEBRXXbNNaSs/vwyt6vgq+jIiAhpg1MtqNdmhOt3k6K7V4wH5p5IxNvRXAoP51rAHyig0f4egsM+WdCQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<graphics-element id="graphics" width="200px" height="160px" title="let's draw some roses">
  <graphics-source>
    const r = 70;
    let k = 1;

    function setup() {
      addSlider(`n`, {min:1, max:7, step:1, value:1 });
      addSlider(`d`, {min:1, max:9, step:1, value:3 });
    }
    
    function draw() {
      k = n / d;
      clear();
      noFill();
      translate(width/2, height/2);
      start();
      const oddN = (n % 2) === 1;
      const oddD = (d % 2) === 1;
      const limit = d * ((oddN && oddD) ? PI : TAU);
      for (let theta = 0, f, x, y; theta <= limit; theta += 0.001) {
        f = r * cos(k * theta);
        x = f * cos(theta);
        y = f * sin(theta);
        vertex(x, y);
     }
     end();
    }
  </graphics-source>
</graphics-element>

© www.soinside.com 2019 - 2024. All rights reserved.