Интересно, а можно ли используя какое-нибудь уравнение, получить график, отображающий лист конопли ?
Оказывается, это вполне реально, и к нашим услугам три разных уравнения, дающие один и тот же рисунок:
[1] (1 + sin(phi)) * (1.0 + 0.9 * cos(8 * phi)) * (1.0 + 0.1 * cos(24 * phi)) [2] (1.0 + sin(phi)) * (1.0 - 0.9 * fabs(sin(4 * phi))) * (0.9 + 0.05 * cos(200 * phi)) [3] (1.0 + sin(phi)) * (1.0 + 0.9 * cos(8 * phi)) * (1.0 + 0.1 * cos(24 * phi)) * (0.5 + 0.05 * cos(140 * phi))
Но… Все это рисовать нужно в полярных координатах, которые преобразуются в декартовы элементарнейшим способом:
auto x = r * cos(phi); auto y = r * sin(phi);
Ну и код всего приложения:
import dgui.all; import std.math; // отрисовка отдельных точек void drawPoint(Canvas c, int x, int y) { Pen p = new Pen(SystemColors.darkGreen, 1, PenStyle.solid); c.drawLine(p, x, y, x + 1, y + 1); }; // отрисовка конопли float cannabola1(float phi) { return (1 + sin(phi)) * (1.0 + 0.9 * cos(8 * phi)) * (1.0 + 0.1 * cos(24 * phi)); } float cannabola2(float phi) { return (1.0 + sin(phi)) * (1.0 - 0.9 * fabs(sin(4 * phi))) * (0.9 + 0.05 * cos(200 * phi)); } float cannabola3(float phi) { return (1.0 + sin(phi)) * (1.0 + 0.9 * cos(8 * phi)) * (1.0 + 0.1 * cos(24 * phi)) * (0.5 + 0.05 * cos(140 * phi)); } void drawCannabola(Canvas c) { for (float phi = -360.0; phi < 360.0; phi += 0.005) { auto r = cannabola1(phi); auto x = r * cos(phi); auto y = r * sin(phi); auto coordX = cast(int) (250 - 60 * x); auto coordY = cast(int) (450 - 60 * y); drawPoint(c, coordX, coordY); } } class MainForm : Form { public this() { this.text = ""; this.size = Size(500, 550); this.startPosition = FormStartPosition.centerScreen; }; protected override void onPaint(PaintEventArgs e) { Canvas c = e.canvas; drawCannabola(c); super.onPaint(e); } }; int main(string[] args) { return Application.run(new MainForm()); }
Результат (для функции cannabola3):