4

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&lt;float&gt; integerVector;       // вектор куда кладём точки (Х и У)
QVector&lt;QPointF&gt; 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&lt;_mytKrg.kol_toch; ++i)
{
    if(i &gt; tocka_1)          // угол &quot;вырезания&quot;  начало
    {
        d_t =  false;
        if( i &lt; tocka_2)      // угол &quot;вырезания&quot; конец
        {
            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() &lt;&lt; &quot;i :&quot;&lt;&lt;i;
        qDebug() &lt;&lt; &quot;_mytKrg.tocka_1 :&quot;&lt;&lt;_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

timob256
  • 143
  • 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 – user2661923 Nov 01 '21 at 07:09
  • 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 – user2661923 Nov 01 '21 at 07:11
  • [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 – user2661923 Nov 01 '21 at 07:17
  • I suggest first nailing down the math to manually verify that the math formulas are correct. Then, once you choose the software package, if your software is malfunctioning, you would then want to consult a forum dedicated to that specific software package, in order to get help diagnosing your software bug. – user2661923 Nov 01 '21 at 07:19
  • 1
    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). – user2661923 Nov 01 '21 at 07:25
  • 4
    $\sin^{-1}(k)$ is the inverse sine function ( asin(k) in C) , not sin(1) as in your code. – achille hui Nov 01 '21 at 07:32

2 Answers2

4

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, 2pi, 0.05): theta.append(t) nom = np.cos((2np.arcsin(k)+pim)/(2n)) denom = np.cos((2np.arcsin(knp.cos(nt))+pim)/(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

  • 1
    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 ?? – timob256 Nov 01 '21 at 14:04
  • You are welcome. I am happy that it was helpful for you. –  Nov 01 '21 at 15:53
  • 1
    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)$. –  Nov 01 '21 at 17:20
  • 1
    Nice. so finally what are the geometric meanings of $(k,m)?$ Can we also draw regular polygons? – Narasimham Nov 03 '21 at 12:24
  • 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. –  Nov 03 '21 at 13:21
1

$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]
Narasimham
  • 40,495