2 * Copyright 2010-2011, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Geoffry Song, goffrie@gmail.com
7 * Ryan Leavengood, leavengood@gmail.com
11 #include "Butterfly.h"
17 #include <DefaultSettingsView.h>
21 #undef B_TRANSLATION_CONTEXT
22 #define B_TRANSLATION_CONTEXT "Screensaver Butterfly"
25 extern "C" BScreenSaver
*
26 instantiate_screen_saver(BMessage
* archive
, image_id imageId
)
28 return new Butterfly(archive
, imageId
);
35 Butterfly::Butterfly(BMessage
* archive
, image_id imageId
)
37 BScreenSaver(archive
, imageId
)
43 Butterfly::StartConfig(BView
* view
)
45 BPrivate::BuildDefaultSettingsView(view
, "Butterfly",
46 B_TRANSLATE("by Geoffry Song"));
51 Butterfly::StartSaver(BView
* view
, bool preview
)
53 view
->SetLowColor(0, 0, 0);
54 view
->FillRect(view
->Bounds(), B_SOLID_LOW
);
55 view
->SetDrawingMode(B_OP_ALPHA
);
56 view
->SetBlendingMode(B_CONSTANT_ALPHA
, B_ALPHA_OVERLAY
);
57 view
->SetLineMode(B_ROUND_CAP
, B_ROUND_JOIN
);
59 view
->SetPenSize(2.0);
63 // Set fBase to a random radian value scaled by 1000. The scaling produces
64 // more interesting results.
65 srand48(system_time());
66 fBase
= drand48() * 2 * M_PI
* 1000;
68 // calculate transformation
69 BRect bounds
= view
->Bounds();
70 fScale
= MIN(bounds
.Width(), bounds
.Height()) * 0.1f
;
71 fTrans
.Set(bounds
.Width() * 0.5f
, bounds
.Height() * 0.5f
);
74 fLast
[0] = _Iterate();
75 fLast
[1] = _Iterate();
76 fLast
[2] = _Iterate();
83 Butterfly::Draw(BView
* view
, int32 frame
)
86 // calculate bounding box ( (-5.92,-5.92) to (5.92, 5.92) )
87 fBounds
.Set(-5.92f
* fScale
+ fTrans
.x
, -5.92f
* fScale
+ fTrans
.y
,
88 5.92f
* fScale
+ fTrans
.x
, 5.92f
* fScale
+ fTrans
.y
);
90 if ((frame
& 3) == 0) {
92 view
->SetHighColor(0, 0, 0, 4);
93 view
->FillRect(fBounds
);
95 // create a color from a hue of (fBase * 15) degrees
96 view
->SetHighColor(_HueToColor(fBase
* 15));
97 BPoint p
= _Iterate();
99 // cubic Hermite interpolation from fLast[1] to fLast[2]
100 // calculate tangents for a Catmull-Rom spline
101 //(these values need to be halved)
102 BPoint m1
= fLast
[2] - fLast
[0]; // tangent for fLast[1]
103 BPoint m2
= p
- fLast
[1]; // tangent for fLast[2]
105 // draw Bezier from fLast[1] to fLast[2] with control points
106 // fLast[1] + m1/3, fLast[2] - m2/3
111 BPoint control
[4] = { fLast
[1], fLast
[1] + m1
, fLast
[2] - m2
, fLast
[2] };
112 view
->StrokeBezier(control
);
120 //! Convert from a hue in degrees to a fully saturated color
122 Butterfly::_HueToColor(float hue
)
124 // convert from [0..360) to [0..1530)
125 int h
= static_cast<int>(fmodf(hue
, 360) * 4.25f
);
126 int x
= 255 - abs(h
% 510 - 255);
128 rgb_color result
= {0, 0, 0, 255};
132 } else if (h
< 510) {
135 } else if (h
< 765) {
138 } else if (h
< 1020) {
141 } else if (h
< 1275) {
153 Butterfly::_Iterate()
155 float r
= powf(M_E
, cosf(fBase
)) - 2 * cosf(4 * fBase
)
156 - powf(sinf(fBase
/ 12), 5);
157 // rotate and move it a bit
158 BPoint
p(sinf(fBase
* 1.01f
) * r
+ cosf(fBase
* 1.02f
) * 0.2f
,
159 cosf(fBase
* 1.01f
) * r
+ sinf(fBase
* 1.02f
) * 0.2f
);
160 // transform to view coordinates