Slightly improved Blob.

This commit is contained in:
23rd 2020-12-01 14:13:01 +03:00
parent c8c29c7c78
commit dffa36ede4
3 changed files with 51 additions and 48 deletions

View file

@ -31,13 +31,9 @@ BlobBezier::BlobBezier(int n, float minScale, float minSpeed, float maxSpeed)
, _minScale(minScale) , _minScale(minScale)
, _minSpeed(minSpeed ? minSpeed : kMinSpeed) , _minSpeed(minSpeed ? minSpeed : kMinSpeed)
, _maxSpeed(maxSpeed ? maxSpeed : kMaxSpeed) , _maxSpeed(maxSpeed ? maxSpeed : kMaxSpeed)
, _pen(Qt::NoBrush, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin) { , _pen(Qt::NoBrush, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)
_radius.resize(n); , _segmentAngle(360. / n)
_angle.resize(n); , _segments(n) {
_radiusNext.resize(n);
_angleNext.resize(n);
_progress.resize(n);
_speed.resize(n);
} }
void BlobBezier::paint(Painter &p, const QBrush &brush) { void BlobBezier::paint(Painter &p, const QBrush &brush) {
@ -51,17 +47,22 @@ void BlobBezier::paint(Painter &p, const QBrush &brush) {
} }
for (auto i = 0; i < _segmentsCount; i++) { for (auto i = 0; i < _segmentsCount; i++) {
const auto progress = _progress[i]; const auto &segment = _segments[i];
const auto nextIndex = i + 1 < _segmentsCount ? (i + 1) : 0; const auto nextIndex = i + 1 < _segmentsCount ? (i + 1) : 0;
const auto progressNext = _progress[nextIndex]; const auto nextSegment = _segments[nextIndex];
const auto r1 = _radius[i] * (1. - progress)
+ _radiusNext[i] * progress; const auto progress = segment.progress;
const auto r2 = _radius[nextIndex] * (1. - progressNext) const auto progressNext = nextSegment.progress;
+ _radiusNext[nextIndex] * progressNext;
const auto angle1 = _angle[i] * (1. - progress) const auto r1 = segment.radius * (1. - progress)
+ _angleNext[i] * progress; + segment.radiusNext * progress;
const auto angle2 = _angle[nextIndex] * (1. - progressNext) const auto r2 = nextSegment.radius * (1. - progressNext)
+ _angleNext[nextIndex] * progressNext; + nextSegment.radiusNext * progressNext;
const auto angle1 = segment.angle * (1. - progress)
+ segment.angleNext * progress;
const auto angle2 = nextSegment.angle * (1. - progressNext)
+ nextSegment.angleNext * progressNext;
const auto l = _segmentLength * (std::min(r1, r2) const auto l = _segmentLength * (std::min(r1, r2)
+ (std::max(r1, r2) - std::min(r1, r2)) / 2.); + (std::max(r1, r2) - std::min(r1, r2)) / 2.);
@ -95,35 +96,33 @@ void BlobBezier::paint(Painter &p, const QBrush &brush) {
void BlobBezier::generateBlob() { void BlobBezier::generateBlob() {
for (auto i = 0; i < _segmentsCount; i++) { for (auto i = 0; i < _segmentsCount; i++) {
generateBlob(_radius, _angle, i); auto &segment = _segments[i];
generateBlob(_radiusNext, _angleNext, i); generateBlob(segment.radius, segment.angle, i);
_progress[i] = 0; generateBlob(segment.radiusNext, segment.angleNext, i);
segment.progress = 0.;
} }
} }
void BlobBezier::generateBlob( void BlobBezier::generateBlob(float &radius, float &angle, int i) {
std::vector<float> &radius, const auto angleDiff = _segmentAngle * 0.05;
std::vector<float> &angle,
int i) {
const auto angleSegment = 360. / _segmentsCount;
const auto angleDiff = angleSegment * 0.05;
const auto radDiff = _maxRadius - _minRadius; const auto radDiff = _maxRadius - _minRadius;
radius[i] = _minRadius + std::abs(RandomAdditional()) * radDiff; radius = _minRadius + std::abs(RandomAdditional()) * radDiff;
angle[i] = angleSegment * i + RandomAdditional() * angleDiff; angle = _segmentAngle * i + RandomAdditional() * angleDiff;
_speed[i] = 0.017 + 0.003 * std::abs(RandomAdditional()); _segments[i].speed = 0.017 + 0.003 * std::abs(RandomAdditional());
} }
void BlobBezier::update(float level, float speedScale) { void BlobBezier::update(float level, float speedScale) {
_scale = level; _scale = level;
for (auto i = 0; i < _segmentsCount; i++) { for (auto i = 0; i < _segmentsCount; i++) {
_progress[i] += (_speed[i] * _minSpeed) auto &segment = _segments[i];
+ level * _speed[i] * _maxSpeed * speedScale; segment.progress += (segment.speed * _minSpeed)
if (_progress[i] >= 1) { + level * segment.speed * _maxSpeed * speedScale;
_progress[i] = 0.; if (segment.progress >= 1) {
_radius[i] = _radiusNext[i]; segment.progress = 0.;
_angle[i] = _angleNext[i]; segment.radius = segment.radiusNext;
generateBlob(_radiusNext, _angleNext, i); segment.angle = segment.angleNext;
generateBlob(segment.radiusNext, segment.angleNext, i);
} }
} }
} }

View file

@ -18,15 +18,20 @@ public:
void update(float level, float speedScale); void update(float level, float speedScale);
void generateBlob(); void generateBlob();
void setRadius(float min, float max);
void setMinRadius(float value); void setMinRadius(float value);
void setMaxRadius(float value); void setMaxRadius(float value);
private: private:
void generateBlob( struct Segment {
std::vector<float> &radius, float radius = 0.;
std::vector<float> &angle, float angle = 0.;
int i); float radiusNext = 0.;
float angleNext = 0.;
float progress = 0.;
float speed = 0.;
};
void generateBlob(float &radius, float &angle, int i);
const int _segmentsCount; const int _segmentsCount;
const float64 _segmentLength; const float64 _segmentLength;
@ -34,13 +39,9 @@ private:
const float _minSpeed; const float _minSpeed;
const float _maxSpeed; const float _maxSpeed;
const QPen _pen; const QPen _pen;
const float _segmentAngle;
std::vector<float> _radius; std::vector<Segment> _segments;
std::vector<float> _angle;
std::vector<float> _radiusNext;
std::vector<float> _angleNext;
std::vector<float> _progress;
std::vector<float> _speed;
float64 _scale = 0; float64 _scale = 0;
float _minRadius = 0.; float _minRadius = 0.;

View file

@ -15,7 +15,7 @@ Blobs::Blobs(
float levelDuration, float levelDuration,
float maxLevel) float maxLevel)
: _maxLevel(maxLevel) : _maxLevel(maxLevel)
, _blobDatas(blobDatas) , _blobDatas(std::move(blobDatas))
, _levelValue(levelDuration) { , _levelValue(levelDuration) {
init(); init();
} }
@ -75,6 +75,9 @@ void Blobs::paint(Painter &p, const QBrush &brush) {
p.setOpacity(opacity * alpha); p.setOpacity(opacity * alpha);
} }
_blobs[i].paint(p, brush); _blobs[i].paint(p, brush);
if (alpha != 1.) {
p.setOpacity(opacity);
}
} }
} }