我试图生成一个包含n个点的数组,这些点在C语言中等距分布在一个圆上。基本上,我需要传递一个函数我想要生成的点数,然后得到一个点的数组。
我已经很久没有使用C/C++了,所以我试着写了一些代码来计算分数,以此来测试自己的能力。这是一个VS2010控制台应用程序。
// CirclePoints.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "stdio.h"
#include "math.h"
int _tmain()
{
int points = 8;
double radius = 100;
double step = ((3.14159265 * 2) / points);
double x, y, current = 0;
for (int i = 0; i < points; i++)
{
x = sin(current) * radius;
y = cos(current) * radius;
printf("point: %d x:%lf y:%lf\n", i, x, y);
current += step;
}
return 0;
}
试试这个:
void make_circle(float *output, size_t num, float radius)
{
size_t i;
for(i = 0; i < num; i++)
{
const float angle = 2 * M_PI * i / num;
*output++ = radius * cos(angle);
*output++ = radius * sin(angle);
}
}
这是未经测试的,角度步骤计算中可能会出现一个偏差,但应该很接近。
当然,这是基于我正确理解问题的前提。
更新:重新计算角度,不再进行递增操作,以减少由于重复加法而导致的浮点精度损失。
angle = i * 2 * M_PI / num;
。 - cafcos
和sin
仅一次,然后循环获取复值cos(angle)+i*sin(angle)
的幂来解决问题。这种方法速度将会快得多。 - R.. GitHub STOP HELPING ICEdouble
而不是 float
可能会更加弥补,除非 n
非常大。void make_circle(double *dest, size_t n, double r)
{
double x0 = cos(2*M_PI/n), y0 = sin(2*M_PI/n), x=x0, y=y0, tmp;
for (;;) {
*dest++ = r*x;
*dest++ = r*y;
if (!--n) break;
tmp = x*x0 - y*y0;
y = x*y0 + y*x0;
x = tmp;
}
}
n
很大时会累积误差,但感谢你的改进。 :-) - R.. GitHub STOP HELPING ICEfunction circlePoints (radius, numPoints, centerX, centerY) {
centerX = centerX || 0;
centerY = centerY || 0;
var
step = (Math.PI * 2) / numPoints,
current = 0,
i = 0,
results = [],
x, y;
for (; i < numPoints; i += 1) {
x = centerX + Math.sin(current) * radius;
y = centerY + Math.cos(current) * radius;
results.push([x,y]);
console.log('point %d @ x:%d, y:%d', i, x, y);
current += step;
}
return results;
}