#c #geometry
#c #геометрия
Вопрос:
Я пытаюсь сгенерировать массив из n точек, которые равноудалены друг от друга и лежат на окружности в C. В принципе, мне нужно иметь возможность передать функции количество точек, которое я хотел бы сгенерировать, и получить обратно массив точек.
Ответ №1:
Прошло действительно много времени с тех пор, как я работал на 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:%lfn", i, x, y);
current = step;
}
return 0;
}
Комментарии:
1. Я выбираю это как принятый ответ, потому что вы показали мне, как получить x и y точек, которые мне были нужны для моего проекта. Могу ли я получить объяснение математики? Мне всего 13, поэтому, пожалуйста, постарайтесь, чтобы ваше объяснение было как можно более простым.
Ответ №2:
Попробуйте что-то вроде этого:
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);
}
}
Это непроверено, возможно, при вычислении шага угла скрытие по одному, но оно должно быть близко.
Это предполагает, конечно, что я правильно понял вопрос.
ОБНОВЛЕНИЕ: Переделано вычисление угла так, чтобы оно не увеличивалось, чтобы уменьшить потерю точности с плавающей точкой из-за повторного добавления.
Комментарии:
1. Повторяющиеся добавления приведут к накоплению ошибок — вам лучше использовать
angle = i * 2 * M_PI / num;
в цикле.2. В качестве альтернативы, если вас не волнует накопление незначительных ошибок, вы можете получить, вычислив
cos
иsin
только один раз, затем выполнить цикл, чтобы получить степени комплексного значенияcos(angle) i*sin(angle)
. Так будет намного быстрее.
Ответ №3:
Вот решение, несколько оптимизированное, непроверенное. Ошибка может накапливаться, но использование double
вместо 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;
}
}
Комментарии:
1. Если быть по-настоящему разборчивым, при больших n вы немного потеряете точность, обновляя x и y таким образом, потому что x0 будет близко к 1. Вы теряете меньшую точность, используя d0 = cos (2pi / n) -1 = -2 * sin (pi / n) * sin (pi / n), а затем обновляете: tmp = x d0-y y0; y = x d0 y x0; x = tmp;
2. Честно говоря, я сказал, что вы будете накапливать ошибку для больших
n
, но спасибо за улучшение. 🙂
Ответ №4:
Вы должны решить это на языке c:
В декартовой системе координат x-y окружность с координатами центра (a, b) и радиусом r является множеством всех точек (x, y), таких, что
(x — a) ^ 2 (y — b) ^ 2 = r ^ 2
Комментарии:
1. Вот почему я пишу необычные решения и призываю OP объяснить это своему профессору, если они будут копировать это дословно … 😉
Ответ №5:
Вот реализация javascript, которая также использует необязательную центральную точку.
function 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;
}
Комментарии:
1. Привет, и добро пожаловать в Stack Overflow. Хотя это должно быть тривиально для перевода на C, пожалуйста, придерживайтесь тегов в будущих ответах. Это C-вопрос, и на него следует дать C-ответы.