1 module rip.draw.mathgraphics;
2 
3 private
4 {
5 	import std.algorithm;
6 	import std.math;
7 	import std.range;
8 	import std.traits;
9 
10 	import rip.concepts;
11 
12 	import rip.draw.primitives : drawPoint;
13 
14 	// отрисовка по сразу двум параметрам-диапазонам
15 	// не предназначена для внешнего использования
16 	auto drawTwoRanges(First, Second)(Surface surface, RGBColor rgbColor,
17 		First first, Second second)
18 		if (allArithmetic!(ElementType!First, ElementType!Second))
19 	{
20 		assert(!first.empty);
21 		assert(!second.empty);
22 
23 		foreach (xy; zip(first, second))
24 		{
25 			surface.drawPoint(rgbColor, xy[0], xy[1]);
26 		}
27 	}
28 }
29 
30 alias drawDiscrete = drawTwoRanges; // рисование последовательностей
31 
32 // график некоторой функции на непрерывном диапазоне
33 auto drawFunctional(T, U, Range)(Surface surface, RGBColor rgbColor,
34 	T delegate(U) func, Range r)
35 	if (isInputRange!(Unqual!Range) && allArithmetic!(T, U, ElementType!Range))
36 {
37 	assert(!r.empty);
38 
39 	auto ys = map!(a => func(a))(r);
40 
41 	drawTwoRanges(surface, rgbColor, r, ys);
42 }
43 
44 
45 // график параметрической функции
46 auto drawParametrical(T, U, V, W, Range)(Surface surface, RGBColor rgbColor,
47 	T delegate(U) funcX, V delegate(W) funcY, Range r)
48 	if (isInputRange!(Unqual!Range) && allArithmetic!(T, U, V, W, ElementType!Range))
49 {
50 
51 	auto xs = map!(a => funcX(a))(r);
52 	auto ys = map!(a => funcY(a))(r);
53 
54 	drawTwoRanges(surface, rgbColor, xs, ys);
55 }
56 
57 
58 // рисование функции в полярных координатах (углы в градусах)
59 auto drawPolarInDegrees(T, U, Range)(Surface surface, RGBColor rgbColor,
60 	T delegate(U) func, Range r)
61 	if (isInputRange!(Unqual!Range) && allArithmetic!(T, U, ElementType!Range))
62 {
63 	assert(!r.empty);
64 
65 	auto phi = map!(a => a * (PI / 180.0))(r).array;
66 	auto xs = map!(a => func(a) * cos(a))(phi);
67 	auto ys = map!(a => func(a) * sin(a))(a);
68 
69 	drawTwoRanges(surface, rgbColor, r, ys);
70 }
71 
72 
73 // рисование функции в полярных координатах (углы в радианах)
74 auto drawPolarInRadians(T, U, Range)(Surface surface, RGBColor rgbColor,
75 	T delegate(U) func, Range r)
76 	if (isInputRange!(Unqual!Range) && allArithmetic!(T, U, ElementType!Range))
77 {
78 	assert(!r.empty);
79 
80 	auto xs = map!(a => func(a) * cos(a))(r);
81 	auto ys = map!(a => func(a) * sin(a))(r);
82 
83 	drawTwoRanges(surface, rgbColor, r, ys);
84 }