質問
私は数学が苦手な 2 つの点 (中心と頂点の 1 つ) を与えられて「n」個の辺の多角形を描く必要があります。私はたくさん読んできましたが、これが私が理解できたことです(それが正しいかどうかはわかりません)。
OK、ピタゴラスの定理を使って 2 点間の距離 (半径) を求めます。
sqrt(pow(abs(x - xc), 2) + pow(abs(y - yc), 2));
そして、atan2 を使用したこの 2 点間の角度は次のようになります。
atan2(abs(y - yc), abs(x - xc));
ここで、xc、yc は中心点であり、x、y が唯一の頂点として認識されます。
そして、そのデータを使って次のようにします。
void polygon(int xc, int yc, int radius, double angle, int sides)
{
int i;
double ang = 360/sides; //Every vertex is about "ang" degrees from each other
radian = 180/M_PI;
int points_x[7]; //Here i store the calculated vertexs
int points_y[7]; //Here i store the calculated vertexs
/*Here i calculate the vertexs of the polygon*/
for(i=0; i<sides; i++)
{
points_x[i] = xc + ceil(radius * cos(angle/radian));
points_y[i] = yc + ceil(radius * sin(angle/radian));
angle = angle+ang;
}
/*Here i draw the polygon with the know vertexs just calculated*/
for(i=0; i<sides-1; i++)
line(points_x[i], points_y[i], points_x[i+1], points_y[i+1]);
line(points_y[i], points_x[i], points_x[0], points_y[0]);
}
問題は、多角形のように線を描画しないため、プログラムが正しく動作しないことです。
誰かが手伝ってくれるほど数学に詳しい人はいますか?私は C と Turbo C を使用してこのグラフィックス プリミティブを作成しています。
編集:多角形を塗りつぶすのではなく、ただ描くだけです。
解決
何を考えてください 360/sides
実際に返されるのは次の場合です sides
は 360 の因数ではありません (これは整数の除算です - 360/7 が実際に何を返すかを見てください)。
学位を使用する必要はまったくありません。 2*Math_PI/(double)nsides
ラジアン単位で動作します。
また、modulus 関数 (module nsides) を使用して最終行を省略することもできます。
7 面を超える場合は、すべてのポイントを保存することができません。ポリゴンを保存するのではなく単に描画する場合は、すべてのポイントを保存する必要はありません。最後のポイントと現在のポイントだけを保存するだけです。
他のヒント
すべての計算ではラジアンを使用する必要があります。これを行う最善の方法を示す完全なプログラムを次に示します。
#include <stdio.h>
#define PI 3.141592653589
static void line (int x1, int y1, int x2, int y2) {
printf ("Line from (%3d,%3d) - (%3d,%3d)\n", x1, y1, x2, y2);
}
static void polygon (int xc, int yc, int x, int y, int n) {
int lastx, lasty;
double r = sqrt ((x - xc) * (x - xc) + (y - yc) * (y - yc));
double a = atan2 (y - yc, x - xc);
int i;
for (i = 1; i <= n; i++) {
lastx = x; lasty = y;
a = a + PI * 2 / n;
x = round ((double)xc + (double)r * cos(a));
y = round ((double)yc + (double)r * sin(a));
line (lastx, lasty, x, y);
}
}
int main(int argc, char* argv[]) {
polygon (0,0,0,10,4); // A diamond.
polygon (0,0,10,10,4); // A square.
polygon (0,0,0,10,8); // An octagon.
return 0;
}
出力は次のとおりです (ここには派手なグラフィックはありませんが、アイデアは理解できるはずです)。
===
Line from ( 0, 10) - (-10, 0)
Line from (-10, 0) - ( 0,-10)
Line from ( 0,-10) - ( 10, 0)
Line from ( 10, 0) - ( 0, 10)
===
Line from ( 10, 10) - (-10, 10)
Line from (-10, 10) - (-10,-10)
Line from (-10,-10) - ( 10,-10)
Line from ( 10,-10) - ( 10, 10)
===
Line from ( 0, 10) - ( -7, 7)
Line from ( -7, 7) - (-10, 0)
Line from (-10, 0) - ( -7, -7)
Line from ( -7, -7) - ( 0,-10)
Line from ( 0,-10) - ( 7, -7)
Line from ( 7, -7) - ( 10, 0)
Line from ( 10, 0) - ( 7, 7)
Line from ( 7, 7) - ( 0, 10)
私が書いたのは、 polygon
2 つの座標だけを渡して、元の仕様に従って機能します。余談ですが、あなたはそうではありません 欲しい それらの abs
次の理由により、半径と角度の計算が呼び出されます。
- それらは半径には役に立たない(なぜなら
-n
2
=n
2
すべてのためにn
). - 特定の象限(間違った開始点)に押し込まれるため、角度には悪影響を及ぼします。
私はあなたに答えを与えるつもりはないが、私はいくつかのアドバイスを持っています。まず、線画は、内と外をどのように動作するかを学びます。あなたは、このダウンを持っている場合は、黒三角レンダラを書いてみます。 一般に、充填されたポリゴンは、一度に1本の水平走査線、上から下へ引かれます。あなたはしているジョブが開始および停止xは、すべての走査線のための座標を決定することです。ポリゴンのエッジが...直線(ヒント、ヒント)を次のことに注意してください。)
あなたは、ポリ私は推測いっぱい描くしようとしている?
あなたは原始的なラインを使用してポリゴンを描画しようとしている場合は、は、あなたはあなたに来て多くの痛みを持っているつもりです。 dicroceは、実際にその前にあなたにいくつかの非常に良いアドバイスを与えます。
あなたの最善の策は、プリミティブを見つけることであるあなたと供給その座標リストの塗りつぶし。それはそれを与えるために座標を決定するのはあなた次第です。
私は、メインのトラブルがあると思う:。atan2(abs(y - yc), abs(x - xc));
はちょうど度に変換してみてください、あなたはラジアンない度を与えている。
/* all angles in radians */
double ainc = PI*2 / sides;
int x1, y1;
for (i = 0; i <= sides; i++){
double a = angle + ainc * i;
int x = xc + radius * cos(a);
int y = yc + radius * sin(a);
if (i > 0) line(x1, y1, x, y);
x1 = x; y1 = y;
}
それとも、あなたは配列内のポイントを保存して、あなたは1を持っている場合DrawPolyルーチンを呼び出すことができます。
あなたが満たされた多角形をしたい場合は1を持っている場合は、FillPolyを呼び出します。