Files
Renderive/YSGraphic_Core/plottable/Planisphere_p.h
T
2026-07-28 10:54:38 +08:00

151 lines
5.6 KiB
C++

#pragma once
#include <cstddef>
#include <cstring>
#include "../Axis/Axis.h"
#include "../architecture/Bounded_Input_Buffer.h"
#include "../architecture/Plot_p.h"
#include "Planisphere.h"
namespace YSG {
struct PlanisphereData {
QPointF mPos;
int mRemainTimes{};
int maxTotalTimes{};
};
struct Planisphere_Input_Data : Input_Data {
struct Packet {
double x{};
double y{};
};
Bounded_Input_Buffer mDataList;
void push(QPointF pos) {
Packet packet{pos.x(), pos.y()};
mDataList.push(&packet, sizeof(packet));
}
template <typename Handler>
void read_all(Handler handler) {
mDataList.read_all([&handler](const void* data, std::size_t size) {
(void)size;
Packet packet;
std::memcpy(&packet, data, sizeof(packet));
handler(QPointF(packet.x, packet.y));
});
}
void clear() override {
mDataList.clear();
}
std::uint64_t pending_count() const override {
return mDataList.pending_count();
}
std::uint64_t dropped_count() const override {
return mDataList.dropped_count();
}
std::uint64_t pushed_count() const override {
return mDataList.pushed_count();
}
};
struct Planisphere_Render_State : Render_State, Planisphere_Prop {};
struct Planisphere_Private : Typed_Render_Data<Planisphere, Planisphere_Render_State, Planisphere_Input_Data> {
friend class Planisphere;
std::list<PlanisphereData> dataList;
QVector<double> xs, ys;
QVector<QPointF> fixedPoints;
void update_fixed_points() {
Planisphere_Render_State* s = render_state();
fixedPoints.clear();
if (s->type == Planisphere_Type::Psk8) {
double xS = s->i_axis->coord_to_pixel(s->i_range.lower, SRC::Render);
double yS = s->q_axis->coord_to_pixel(s->q_range.lower, SRC::Render);
double xL = s->i_axis->coord_to_pixel(s->i_range.upper, SRC::Render) - xS;
double yL = s->q_axis->coord_to_pixel(s->q_range.upper, SRC::Render) - yS;
double xSpace = xL / 6.0;
double ySpace = yL / 6.0;
double xLineSpace = xL / 4.0;
double yLineSpace = yL / 4.0;
fixedPoints.push_back({xS + 2 * xSpace, yS + 1 * ySpace});
fixedPoints.push_back({xS + 1 * xSpace, yS + 2 * ySpace});
fixedPoints.push_back({xS + 1 * xSpace, yS + 4 * ySpace});
fixedPoints.push_back({xS + 2 * xSpace, yS + 5 * ySpace});
fixedPoints.push_back({xS + 4 * xSpace, yS + 5 * ySpace});
fixedPoints.push_back({xS + 5 * xSpace, yS + 4 * ySpace});
fixedPoints.push_back({xS + 5 * xSpace, yS + 2 * ySpace});
fixedPoints.push_back({xS + 4 * xSpace, yS + 1 * ySpace});
xs.resize(5);
ys.resize(5);
double curX = xS, curY = yS;
for (int i = 0; i < 5; ++i) {
xs[i] = curX;
curX += xLineSpace;
ys[i] = curY;
curY += yLineSpace;
}
}
}
void refresh() {
for (auto it = dataList.begin(); it != dataList.end();) {
if (--it->mRemainTimes == 0)
dataList.erase(it++);
else
++it;
}
}
void prepare_data() override {
sync_state_pipeline();
Planisphere_Input_Data* d = render_input_data();
Planisphere_Render_State* s = render_state();
int times = qMax(5, (s->continue_millisecond * q()->mPlot->d->mRefreshTimesPreSecond) / 1000);
d->read_all([this, times](const QPointF& pos) {
PlanisphereData data;
data.mPos = pos;
data.maxTotalTimes = times;
data.mRemainTimes = times;
dataList.push_back(data);
});
clear_render_input();
refresh();
}
void draw(QPainter* painter) override {
update_fixed_points();
Planisphere_Render_State* s = render_state();
{
double xS = xs.first(), xE = xs.last();
double yS = ys.first(), yE = ys.last();
QPen pen;
pen.setStyle(Qt::DotLine);
pen.setColor(Qt::white);
painter->setPen(pen);
for (double x : xs)
painter->drawLine(QPointF(x, yS), QPointF(x, yE));
for (double y : ys)
painter->drawLine(QPointF(xS, y), QPointF(xE, y));
}
{
painter->setPen(Qt::NoPen);
for (PlanisphereData& data : dataList) {
QColor c = s->point_color;
c.setAlphaF(c.alphaF() * data.mRemainTimes / data.maxTotalTimes);
painter->setBrush(c);
double centerX = s->i_axis->coord_to_pixel(data.mPos.x(), SRC::Render);
double centerY = s->q_axis->coord_to_pixel(data.mPos.y(), SRC::Render);
double radius = 2;
painter->drawEllipse({centerX - radius, centerY - radius}, 2 * radius, 2 * radius);
}
}
{
painter->setPen(QPen(s->anchor_color, 2));
painter->setBrush(Qt::NoBrush);
QVector<QPointF>& fixedPoints = this->fixedPoints;
for (auto& point : fixedPoints) {
int radius = 6;
painter->drawLine(QPointF{point.x() - radius, point.y()}, {point.x() + radius, point.y()});
painter->drawLine(QPointF{point.x(), point.y() - radius}, {point.x(), point.y() + radius});
}
}
}
void plot_event(QEvent* event) override {
if (event->type() == QEvent::Resize) {
auto e = reinterpret_cast<QResizeEvent*>(event);
}
}
};
} // namespace YSG