#include "pch.h"
#include "MainPage.xaml.h"
#if __has_include("MainPage.g.cpp")
#include "MainPage.g.cpp"
#endif
#include <random>
#include <chrono>
#include <sstream>
#include <ShObjIdl.h>
#include <MainWindow.xaml.h>
using winrt::Windows::Foundation::IInspectable;
using winrt::Windows::Foundation::Rect;
using winrt::Windows::Foundation::TimeSpan;
using winrt::Windows::Foundation::Size;
using winrt::Windows::Graphics::Imaging::SoftwareBitmap;
using winrt::Windows::Graphics::Imaging::BitmapEncoder;
using winrt::Windows::Storage::Pickers::FileOpenPicker;
using winrt::Windows::Storage::Pickers::FileSavePicker;
using winrt::Windows::Storage::Pickers::PickerLocationId;
using winrt::Windows::Storage::StorageFile;
using winrt::Windows::Storage::Streams::IBuffer;
using winrt::Windows::Storage::Streams::IRandomAccessStream;
using winrt::Windows::UI::Color;
using winrt::Microsoft::Graphics::Canvas::CanvasRenderTarget;
using winrt::Microsoft::Graphics::Canvas::CanvasDrawingSession;
using winrt::Microsoft::Graphics::Canvas::CanvasBitmap;
using winrt::Microsoft::Graphics::Canvas::CanvasRenderTarget;
using winrt::Microsoft::Graphics::Canvas::Brushes::CanvasSolidColorBrush;
using winrt::Microsoft::Graphics::Canvas::Text::CanvasTextFormat;
using winrt::Microsoft::Graphics::Canvas::UI::Xaml::CanvasImageSource;
using winrt::Microsoft::UI::Xaml::RoutedEventArgs;
using winrt::Microsoft::UI::Xaml::SizeChangedEventArgs;
using winrt::Microsoft::UI::Xaml::Media::Imaging::RenderTargetBitmap;
constexpr Color CANVAS_BACKGROUND_COLOR{ 0xff, 0xa9, 0xa9, 0xa9 };
constexpr Color CURVES_BACKGROUND_COLOR{ 0xff, 0xff, 0xff, 0xff };
constexpr Color LINE_ONE_COLOR{ 0xff, 0x00, 0xa2, 0xe8 };
constexpr Color LINE_TWO_COLOR{ 0xff, 0x75, 0xfa, 0x8d };
constexpr Color TEXT_COLOR{ 0xff, 0x00, 0x00, 0x00 };
constexpr Color GRID_LINE_COLOR{ 0xff, 0x80, 0x80, 0x80 };
constexpr int LINE_COUNT{ 2 };
constexpr int LINE_POINTS{ 300 };
constexpr int32_t SAMPLING_PERIOD{ 100 };
constexpr size_t DRAWING_PERIOD{ 3 };
constexpr float X_LEFT_PADDING = 40.0f;
constexpr float X_RIGHT_PADDING = 30.0F;
constexpr float Y_TOP_PADDING = 10.0F;
constexpr float Y_BOTTOM_PADDING = 30.0F;
constexpr int GRID_X_COUNT = 15;
constexpr int GRID_Y_COUNT = 20;
constexpr int GRID_FONT_SIZE = 15;
constexpr float X_VALUE_MIN = 0.0F;
constexpr float X_VALUE_MAX = 100.0F;
constexpr float Y_VALUE_MIN = -100.0F;
constexpr float Y_VALUE_MAX = 100.0f;
namespace winrt::Win2dDemo::implementation
{
MainPage::MainPage()
:m_linesData{LINE_COUNT, LINE_POINTS, X_LEFT_PADDING, Y_TOP_PADDING, X_RIGHT_PADDING, Y_BOTTOM_PADDING}
{
}
/// <summary>
/// 获取信号值。
/// 这里采用随机数,模拟采集到的数据。
/// </summary>
/// <param name="minValue">数据范围最小值。</param>
/// <param name="maxValue">数据范围最大值。</param>
/// <returns>每次调用该函数,都返回一个模拟的信号值。</returns>
float MainPage::GetSignalValue(float minValue, float maxValue)
{
static std::random_device device{};
static std::mt19937_64 engine{ device() };
std::uniform_real_distribution<float> dist{ minValue, maxValue };
return dist(engine);
}
void MainPage::Resize()
{
auto size = Win2dCanvas().ActualSize();
m_canvasWidth = size.x;
m_canvasHeight = size.y;
m_linesData.Resize(m_canvasWidth, m_canvasHeight);
}
/// <summary>
/// 初始化绘图区域。
/// </summary>
void MainPage::InitializeCanvas()
{
// 1. 重新计算图片大小。
Resize();
// 2. 重新计算 x 坐标。
if (!m_shouldDrawLines)
{
m_linesData.SetXCoordinates(m_canvasWidth);
m_pointsCounter = 0;
}
// 3. 绘制界面
m_canvasImageSource = CanvasImageSource(Win2dCanvas().Device(), m_canvasWidth, m_canvasHeight, 96.0f);
UIImage().Source(m_canvasImageSource);
auto ds = m_canvasImageSource.CreateDrawingSession(CANVAS_BACKGROUND_COLOR);
DrawGrids(ds);
if (m_shouldDrawLines)
{
DrawLines(ds);
}
}
/// <summary>
/// UI 加载完成,才能初始化绘图区域,否则会报错。
/// </summary>
/// <param name=""></param>
/// <param name=""></param>
void MainPage::LoadedTimer_Tick(IInspectable const&, IInspectable const&)
{
m_textBrush = CanvasSolidColorBrush{ Win2dCanvas(), TEXT_COLOR };
m_textFormat = CanvasTextFormat{};
m_textFormat.FontFamily(L"Consolas");
m_textFormat.FontSize(GRID_FONT_SIZE);
m_textFormat.FontStyle(Windows::UI::Text::FontStyle::Italic);
InitializeCanvas();
m_loadedTimer.Stop();
}
/// <summary>
/// 每100ms,调用一次这个函数。模拟数据采集,并在此更新绘图。
/// </summary>
/// <param name=""></param>
/// <param name=""></param>
void MainPage::DrawLinesTimer_Tick(IInspectable const&, IInspectable const&)
{
if (m_isPaused)
return;
auto t1 = std::chrono::high_resolution_clock::now();
auto validHeight = m_canvasHeight - Y_TOP_PADDING - Y_BOTTOM_PADDING;
m_linesData.SetYCoordinates(0, m_pointsCounter, (1.0f - GetSignalValue(0.1f, 0.3f)) * validHeight + Y_TOP_PADDING);
m_linesData.SetYCoordinates(1, m_pointsCounter, (1.0f - GetSignalValue(0.6f, 0.7f)) * validHeight + Y_TOP_PADDING);
if (++m_pointsCounter % DRAWING_PERIOD == (DRAWING_PERIOD - 1))
{
auto ds = m_canvasImageSource.CreateDrawingSession(CANVAS_BACKGROUND_COLOR);
DrawGrids(ds);
DrawLines(ds);
auto t2 = std::chrono::high_resolution_clock::now();
ShowUsedTime(t1, t2);
}
}
/// <summary>
/// 绘制 X,Y 坐标系。
/// </summary>
/// <param name="ds"></param>
void MainPage::DrawGrids(Microsoft::Graphics::Canvas::CanvasDrawingSession const& ds) const
{
auto validHeight = m_canvasHeight - Y_TOP_PADDING - Y_BOTTOM_PADDING;
auto validWidth = m_canvasWidth - X_LEFT_PADDING - X_RIGHT_PADDING;
float dx = validWidth / GRID_X_COUNT;
float dy = validHeight / GRID_Y_COUNT;
float xOffset = -14.0f;
float yOffset = -10.0f;
ds.FillRectangle(Rect{ X_LEFT_PADDING, Y_TOP_PADDING, validWidth, validHeight }, CURVES_BACKGROUND_COLOR);
constexpr double dxValue = (X_VALUE_MAX - X_VALUE_MIN) / GRID_X_COUNT;
double xValueOffset = max(0.0, 1.0 * m_pointsCounter - LINE_POINTS) * (X_VALUE_MAX - X_VALUE_MIN) / LINE_POINTS;
for (int i = 0; i <= GRID_X_COUNT; i++)
{
auto x = i * dx + X_LEFT_PADDING;
auto y = m_canvasHeight - Y_BOTTOM_PADDING;
double value = round(dxValue * i + xValueOffset);
ds.DrawTextW(winrt::to_hstring(value), float2{ x + xOffset, y }, m_textBrush, m_textFormat);
if (i > 0 && i < GRID_X_COUNT)
ds.DrawLine(float2{ x, y }, float2{ x, Y_TOP_PADDING }, GRID_LINE_COLOR, 1.0f);
}
constexpr double dyValue = (Y_VALUE_MAX - Y_VALUE_MIN) / GRID_Y_COUNT;
for (int i = 1; i < GRID_Y_COUNT; i++)
{
auto x = X_LEFT_PADDING - 30.0f;
auto y = i * dy + Y_TOP_PADDING;
double value = round(dyValue * (GRID_Y_COUNT - i) + Y_VALUE_MIN);
ds.DrawTextW(winrt::to_hstring(value), float2{ x,y + yOffset }, m_textBrush, m_textFormat);
ds.DrawLine(float2{ X_LEFT_PADDING, y }, float2{ m_canvasWidth - X_RIGHT_PADDING, y }, GRID_LINE_COLOR, 1.0F);
}
}
/// <summary>
/// 绘制两条曲线。
/// </summary>
/// <param name="ds"></param>
/// <param name="count"></param>
void MainPage::DrawLines(Microsoft::Graphics::Canvas::CanvasDrawingSession const& ds) const
{
size_t count = min(m_pointsCounter, LINE_POINTS);
for (size_t i = 1; i < count; ++i)
{
ds.DrawLine(m_linesData[0][i - 1], m_linesData[0][i], LINE_ONE_COLOR, 2.0F);
ds.DrawLine(m_linesData[1][i - 1], m_linesData[1][i], LINE_TWO_COLOR, 2.0F);
}
}
void MainPage::ShowUsedTime(std::chrono::high_resolution_clock::time_point t1, std::chrono::high_resolution_clock::time_point t2)
{
auto usedTime = t2 - t1;
std::wstringstream ss;
ss << L"绘图时间: " << usedTime.count() / 1e6 << L"ms";
CostTimeTextBlock().Text(ss.str());
}
/// <summary>
/// 页面加载完成,启动定时器。
/// </summary>
/// <param name=""></param>
/// <param name=""></param>
void MainPage::Pag
DENG-TAO
- 粉丝: 53
- 资源: 1
最新资源
- 预计2030年全球昆虫源饲料市场规模将达到27.4亿美元
- 基于springboot的家政服务管理平台源码(java毕业设计完整源码+LW).zip
- 预计2030年全球铌酸锂薄膜(LNOI)和钽酸锂薄膜(LTOI)市场规模将达到7.7亿美元
- 基于企业微信的客户运营9问9答
- 地级市数字贸易关注度词频数据及城市数字贸易关注度词频数据(2003-2024年).txt
- HTML5 Canvas烟花动画:JavaScript与CSS的结合实现动态效果
- 全新UI-APP分发系统网站源码-全新IPA/APK APP分发平台+对接码支付+密钥生成
- 使用HTML和CSS打造闪烁彩灯的圣诞树网页
- 华为交换机网络设备MIB文件
- 最新更新!!!全国各省、市、县逐年水文数据(降水量)1950-2022
- 预计2030年全球铌酸锂单晶薄膜市场规模将达到4.17亿美元
- SXU-软件工程论文及绘图
- 预计2030年全球一次性刀叉餐具市场规模将达到28.1亿美元
- 预计2030年全球脂质纳米粒子(LNP)生产设备市场规模将达到3亿美元
- 基于springboot的农机电招平台源码(java毕业设计完整源码+LW).zip
- 智慧航道动态监测管理平台
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈