4
$\begingroup$

I can't get the formula right.

There is a formula for an equilateral polygon

enter image description here

I'm trying to translate it into code to draw a five-pointed star enter image description here

Here's how I translated the equation:

_mytKrg.integerVector.append(_mytKrg.X + (_mytKrg.R * cos(2*sin(1)+M_PI*3)/(2*5))/((cos(2*sin(cos(1*5*grad_kol_toch)))+M_PI*3)/(2*5))); //point Х
_mytKrg.integerVector.append(_mytKrg.Y + (_mytKrg.R * sin(2*cos(1)+M_PI*3)/(2*5))/((sin(2*cos(sin(1*5*grad_kol_toch)))+M_PI*3)/(2*5))); //point У

here is the result :

enter image description here

Here's the whole code:

zvezda.pro

#ifndef KRUG_QT_H
#define KRUG_QT_H

#include <QMainWindow>
#include <QDebug>
#include <QPainter>
#include <QPen>
#include <QFont>
#include <QtMath>
#include <QPointF>

// структура для отрисовки круга
struct strKryg
{
    strKryg()
    {
        R = 0.0; kol_toch = 0;
        tocka_1 = 0; tocka_2 = 0;
        X = 0.0; Y = 0.0;
        integerVector.clear();
        point_for_line.clear();
    }
    float R;                            // радиус
    int kol_toch;                       // колич точек которые будут формировать круг
    int tocka_1;                        // точка выреза начало
    int tocka_2;                        // точка выреза конец
    float X; float Y;                   // расположение икса и игрика

    QVector<float> integerVector;       // вектор куда кладём точки (Х и У)
    QVector<QPointF> point_for_line;    // вектор куда кладём QPointf для line
};

class Krug_qt : public QMainWindow
{
    Q_OBJECT

public:
    Krug_qt(QWidget *parent = 0);
    ~Krug_qt();

    void krygVertexArray();
    void vvodZnach(float R, int kol_toch);
    void vvodZnach(float R, int kol_toch, float X, float Y);
    void vvodZnach(float R, int kol_toch, int tocka_1, int tocka_2, float X, float Y);



protected:
    void paintEvent(QPaintEvent *event);
    strKryg     _mytKrg;    // структура круга

};

#endif // KRUG_QT_H

zvezda.cpp

#include "zvezda.h"

Krug_qt::Krug_qt(QWidget *parent)
    : QMainWindow(parent)
{

}

Krug_qt::~Krug_qt()
{

}

void Krug_qt::krygVertexArray()
{
    float grad = 360.0/_mytKrg.kol_toch;
    float grad_kol_toch = 0.0;
    // градусы*M_PI/180 = радианы
    int j;
    for (j = 0; j < _mytKrg.kol_toch; ++j){

        _mytKrg.integerVector.append(_mytKrg.X + (_mytKrg.R * cos(2*sin(1)+M_PI*3)/(2*5))/((cos(2*sin(cos(1*5*grad_kol_toch)))+M_PI*3)/(2*5)));
        _mytKrg.integerVector.append(_mytKrg.Y + (_mytKrg.R * sin(2*cos(1)+M_PI*3)/(2*5))/((sin(2*cos(sin(1*5*grad_kol_toch)))+M_PI*3)/(2*5)));

         grad_kol_toch = grad_kol_toch + grad;
    }
}
void Krug_qt::vvodZnach(float R, int kol_toch)
{
    _mytKrg.R = R;
    _mytKrg.kol_toch = kol_toch;
    _mytKrg.tocka_1 = 0;
    _mytKrg.tocka_2 = 0;
    _mytKrg.X = 0.0;
    _mytKrg.Y = 0.0;
}

void Krug_qt::vvodZnach(float R, int kol_toch, float X, float Y)
{
    _mytKrg.R = R;
    _mytKrg.kol_toch = kol_toch;
    _mytKrg.tocka_1 = 0;
    _mytKrg.tocka_2 = 0;
    _mytKrg.X = X;
    _mytKrg.Y = Y;
}

void Krug_qt::vvodZnach(float R, int kol_toch, int tocka_1, int tocka_2, float X, float Y)
{
    _mytKrg.R = R;
    _mytKrg.kol_toch = kol_toch;
    _mytKrg.tocka_1 = tocka_1;
    _mytKrg.tocka_2 = tocka_2;
    _mytKrg.X = 0.0;
    _mytKrg.Y = 0.0;
}

void Krug_qt::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);                                   // Создаём объект отрисовщика
    QPen pen_abris(Qt::black, 2, Qt::SolidLine, Qt::FlatCap); // кисть обрисовки (компаса)
    painter.setRenderHint(QPainter::Antialiasing);            // убираем резкие кубики
    painter.setPen(pen_abris);                                // Устанавливаем кисть обрисовки
     vvodZnach(200, 180, 600, 400);
    krygVertexArray();                                        // Набираем массив
 
 
    int i; bool d_t;  int tocka_1; int tocka_2;            // используемые переменные
    d_t = true; i = 0; tocka_1 =_mytKrg.tocka_1; tocka_2 = _mytKrg.tocka_2;  // ТОЧКА ОТРИСОВКИ
    for( ; i<_mytKrg.kol_toch; ++i)
    {
        if(i > tocka_1)          // угол "вырезания"  начало
        {
            d_t =  false;
            if( i < tocka_2)      // угол "вырезания" конец
            {
                tocka_1 = i*2;
                d_t = true;
            }
        }
        if(d_t == true)
        {
            // это отдельно все работает полноценный круг
            tocka_2 = tocka_1+1;
            painter.drawPoint(QPointF(_mytKrg.integerVector[tocka_1],_mytKrg.integerVector[tocka_2]));
            tocka_1 = tocka_1 +2;

            qDebug() << "i :"<<i;
            qDebug() << "_mytKrg.tocka_1 :"<<_mytKrg.tocka_1;
         }
    }
}

alas, I can't write on stackoverflow, for some reason they called me maybe because I'm a Russian-speaking man

I'm wondering if it's possible to draw with formulas ?? are there any books or training sites ???


According to the advice of @Homieomorphism. I made changes to the code, but so far I still do not understand how to convert polar coordinates to Cartesian coordinates.

float grad = 360.0/_mytKrg.kol_toch;
float grad_kol_toch = 0.0;
// градусы*M_PI/180 = радианы
int j; float chisl; float znam; float k = 1; float n =5; float m =3;
for (j = 0; j < _mytKrg.kol_toch; ++j)
{
    chisl = cos((2*asin(k)+M_PI/180*m)/(2*n));
    znam  = cos((2*asin(k*cos(n*grad_kol_toch)+M_PI/180))/(2*n));

    _mytKrg.integerVector.append(_mytKrg.X + (_mytKrg.R * (chisl/znam) * cos(grad_kol_toch*M_PI/180.0) ));
    _mytKrg.integerVector.append(_mytKrg.Y + (_mytKrg.R * (chisl/znam) * sin(grad_kol_toch*M_PI/180.0) ));

    grad_kol_toch = grad_kol_toch + grad;
}

enter image description here

$\endgroup$
6
  • $\begingroup$ Although my first instinct is to label the question as off-topic since this sight is devoted to math problems rather than programming problems, I am influenced by the language difficulties that you report. In general, there are two challenges: [1] If you are creating either an $n$ pointed (regular) star or an $n$ pointed (regular) polygon, where regular indicates that all sides are equal, then you first have to do the math. Here, I advise using Cartesian coordinates, and assuming that the dead center of the star or polygon has coordinates $(0,0)$. ...see next comment $\endgroup$ Nov 1, 2021 at 7:09
  • $\begingroup$ So, based on $n$, and based on whether you are constructing a star or polygon, you have to determine the exact number of line segments to construct. Then, for each line segment, you have to determine the starting and ending coordinates for each line segment. So far, the entire challenge is mathematical. ...see next comment $\endgroup$ Nov 1, 2021 at 7:11
  • $\begingroup$ [2] Then, you have to find the right software to construct such a diagram. There are a multitude of software packages to choose from, including Java, C, QT, or (for example) [Latex + a Latex plug-In]. For Latex possibilites see this article and this forum. Regardless of what software that you use, you need to translate the mathematical specifications, base on $n$ and (star or polygon) into code. ...see next comment $\endgroup$ Nov 1, 2021 at 7:17
  • 1
    $\begingroup$ Since mathSE is a math oriented site, it is generally frowned upon to ask that a mathSE reviewer debug any computer code. If you actually have a math-specific question, then I suggest revamping your question to eliminate all code, and limit the question to a specific math problem that you are having difficulty with. However, the gif file in your posting strongly suggests that you have conquered the math (at least with respect to a $5$ pointed start). $\endgroup$ Nov 1, 2021 at 7:25
  • 4
    $\begingroup$ $\sin^{-1}(k)$ is the inverse sine function ( asin(k) in C) , not sin(1) as in your code. $\endgroup$ Nov 1, 2021 at 7:32

2 Answers 2

4
$\begingroup$

Using the given formula for the radius:

$$ r=\frac{\cos\frac{2\arcsin(k)+\pi\cdot m}{2n}}{\cos\frac{2\arcsin(k\cos(n\cdot\theta))+\pi\cdot m}{2n}}=\frac{nom}{denom} $$

I re-implemented the approach based on polar coordinates using Python (since I feel a bit more confident for solving mathematical tasks in Python than in C/C++). The main idea is to generate two arrays of equal size, one contanining the angles theta=[] and one containing the radi r=[] that correspond to the angles. I ran t from $0$ to $2\pi$ in steps of $0.05$, which gives a good resolution for demonstration purpose. Within the loop we append to both arrays the angle $\theta=t$ and the corresponding radius $r$ calculated using the above-given formula:

import numpy as np
import matplotlib.pyplot as plt
from math import pi

m=3
n=5
theta=[]
r=[]
k=1
for t in np.arange(0, 2*pi, 0.05):
    theta.append(t)
    nom = np.cos((2*np.arcsin(k)+pi*m)/(2*n))
    denom = np.cos((2*np.arcsin(k*np.cos(n*t))+pi*m)/(2*n))
    r.append(nom/denom)

fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.plot(theta, r)
ax.set_rmax(2)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.set_rlabel_position(-22.5)
ax.grid(True)

ax.set_title("A {0}-pointed star".format(n), va='bottom')
plt.show()

enter image description here

The notebook is here: https://www.kaggle.com/eldarsultanow/five-pointed-star/

Feel free to adjust parameters to get star shapes with more vertices. When you for example choose $n=6$ and $m=4$ you get the following result:

enter image description here

$\endgroup$
5
  • 1
    $\begingroup$ thank you, your answer helped me a lot, thank you, your answer helped me a lot, I updated the question (I tried to embed it in this code and even moved) , how to translate into Cartesian coordinates ?? $\endgroup$
    – timob256
    Nov 1, 2021 at 14:04
  • $\begingroup$ You are welcome. I am happy that it was helpful for you. $\endgroup$
    – user736865
    Nov 1, 2021 at 15:53
  • 1
    $\begingroup$ In general, you can simply convert the polar coordinates to cartesian as follows: $x=r\cdot\cos\theta$ and $y=r\cdot\sin\theta$. And vice versa $r=\sqrt{x^2+y^2}$ and $\theta=\text{arctan2}(y,x)$. $\endgroup$
    – user736865
    Nov 1, 2021 at 17:20
  • 1
    $\begingroup$ Nice. so finally what are the geometric meanings of $(k,m)?$ Can we also draw regular polygons? $\endgroup$
    – Narasimham
    Nov 3, 2021 at 12:24
  • $\begingroup$ I am not very sure what $k$ does (it makes the lines more "smooth"?). But what I recognized is that $m$ increases the inner radius which decreases the size of the star's spikes. $\endgroup$
    – user736865
    Nov 3, 2021 at 13:21
1
$\begingroup$

$n$ is the number of vertices on unit circle. Unable to guess as yet what $( k,m) $ could represent in the Rose geometrically. In the plot here $ (k,m) = (2,-1.25) $.

enter image description here

In Mathematica code:

rho[t_, k_, m_, 
  n_] = (Cos[(ArcSin[k] + m Pi/2)]/
    n)/(Cos[(ArcSin[k Cos[n t]] + m Pi/2)]/n)
{k, m, n} = {.2, -1.25, 5}
x[t_, k, m, n] = rho[t, k, m, n] Cos[t]; 
y[t_, k, m, n] = rho[t, k, m, n] Sin[t];
ParametricPlot[{x[t, k, m, n], y[t, k, m, n]}, {t, -0, 2 Pi}, 
 PlotStyle -> Red, GridLines -> Automatic]
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .