Day4 SFML+交互式坐标
Day4 SFML+交互式坐标

Day4 SFML+交互式坐标

Day4 —— 交互功能
这是你做物理、化学实验软件最关键的一天

Day4 目标

  1. 鼠标移动 → 实时显示数学坐标(超级实用)
  2. 键盘方向键 → 平移坐标系
  3. 鼠标滚轮 滚动 → 缩放坐标系
  4. 所有函数跟着一起动,完美模拟实验仪器

Day4图形预览

显示坐标系

交互坐标系,左上角显示坐标位置信息

鼠标在第一象限

鼠标在第二象限

鼠标在第三象限

鼠标在第四象限

平移坐标系,键盘方向键上下左右移动

键盘上移动

键盘下移动

键盘左移动

键盘右移动

缩放坐标系,鼠标滚轮滚动

滚轮向上滚动放大

滚轮向下滚动缩小

我直接给你完整可运行代码,复制即用:


文件名:day4_interactive.cpp

#include <SFML/Graphics.hpp>
#include <cmath>

using namespace std;

const int WIN_W = 800;
const int WIN_H = 600;

// 可交互参数:偏移 + 缩放
float offsetX = 0.0f;
float offsetY = 0.0f;
float scale   = 50.0f;

// 数学坐标 → 屏幕坐标(支持平移 + 缩放)
sf::Vector2f toScreen(float x, float y)
{
    return {
        WIN_W / 2.0f + (x + offsetX) * scale,
        WIN_H / 2.0f - (y + offsetY) * scale
    };
}

// 屏幕坐标 → 数学坐标(给鼠标用)
sf::Vector2f toWorld(float sx, float sy)
{
    return {
        (sx - WIN_W/2.0f) / scale - offsetX,
        (WIN_H/2.0f - sy) / scale - offsetY
    };
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(WIN_W, WIN_H), L"SFML Day4 交互式坐标系");
    window.setFramerateLimit(60);

    // 字体(显示鼠标坐标)
    sf::Font font;
    font.loadFromFile("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf");

    sf::Text text;
    text.setFont(font);
    text.setCharacterSize(18);
    text.setFillColor(sf::Color::White);

    // 颜色
    sf::Color gridCol(50,50,70);
    sf::Color axisCol(100,220,255);
    sf::Color sinCol(255,80,80);
    sf::Color cosCol(80,255,80);
    sf::Color paraCol(255,255,80);

    while (window.isOpen())
    {
        sf::Event e;
        while (window.pollEvent(e))
        {
            if (e.type == sf::Event::Closed)
                window.close();

            // 滚轮缩放
            if (e.type == sf::Event::MouseWheelScrolled)
            {
                scale += e.mouseWheelScroll.delta * 5;
                if (scale < 10) scale = 10;
                if (scale > 200) scale = 200;
            }
        }

        // 键盘平移
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))  offsetX += 0.5f;
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) offsetX -= 0.5f;
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))    offsetY -= 0.5f;
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))  offsetY += 0.5f;

        window.clear(sf::Color(18,18,28));

        // === 网格 ===
        for (int x=0;x<=WIN_W;x+=50) {
            sf::Vertex l[] = {{{(float)x,0},gridCol}, {{(float)x,WIN_H},gridCol}};
            window.draw(l,2,sf::Lines);
        }
        for (int y=0;y<=WIN_H;y+=50) {
            sf::Vertex l[] = {{{0,(float)y},gridCol}, {{WIN_W,(float)y},gridCol}};
            window.draw(l,2,sf::Lines);
        }

        // === 坐标轴 ===
        sf::Vertex xAxis[] = {toScreen(-20,0), toScreen(20,0)};
        sf::Vertex yAxis[] = {toScreen(0,-15), toScreen(0,15)};
        xAxis[0].color = axisCol; xAxis[1].color = axisCol;
        yAxis[0].color = axisCol; yAxis[1].color = axisCol;
        window.draw(xAxis,2,sf::Lines);
        window.draw(yAxis,2,sf::Lines);

        // === 绘制函数 ===
        for (float x=-10;x<10;x+=0.04f) {
            float y = sin(x);
            sf::CircleShape p(1.5f);
            p.setPosition(toScreen(x,y));
            p.setFillColor(sinCol);
            window.draw(p);
        }
        for (float x=-10;x<10;x+=0.04f) {
            float y = cos(x);
            sf::CircleShape p(1.5f);
            p.setPosition(toScreen(x,y));
            p.setFillColor(cosCol);
            window.draw(p);
        }
        for (float x=-5;x<5;x+=0.04f) {
            float y = 0.2f*x*x;
            sf::CircleShape p(1.5f);
            p.setPosition(toScreen(x,y));
            p.setFillColor(paraCol);
            window.draw(p);
        }

        // === 鼠标实时坐标 ===
        sf::Vector2i mPos = sf::Mouse::getPosition(window);
        sf::Vector2f wPos = toWorld(mPos.x, mPos.y);
        char buf[100];
        sprintf(buf, "X: %.2f  Y: %.2f", wPos.x, wPos.y);
        text.setString(buf);
        text.setPosition(10,10);
        window.draw(text);

        window.display();
    }
    return 0;
}

Makefile

# 编译器
CXX := g++

# 编译参数:警告 + 调试 + C++11
CXXFLAGS := -Wall -g -std=c++11

# SFML 库(必须放在最后)
LIBS := -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio

# 要编译的源代码(只编译 main.cpp)
SRC := day4_interactive.cpp
OBJ := $(SRC:.cpp=.o)

# 最终生成的程序名
TARGET := app4

# 默认编译
all: $(TARGET)

# 链接生成可执行文件
$(TARGET): $(OBJ)
    $(CXX) $(CXXFLAGS) -o $@ $(OBJ) $(LIBS)

# 编译 cpp 文件
%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

# 清理
clean:
    rm -f $(OBJ) $(TARGET)

# 运行(可选,输入 make run 即可启动)
run: $(TARGET)
    ./$(TARGET)

使用规则

编译:

       make

    运行:

         make run

      清理:

           make clean

        运行命令

        ./app4

        你可以这样操作

        • 方向键:平移坐标系
        • 鼠标滚轮:放大 / 缩小
        • 鼠标移动:左上角实时显示数学坐标(精确到小数点后两位)

        这一天完成后

        你就拥有了 专业数学/物理/化学绘图工具的核心引擎

        发表回复

        您的邮箱地址不会被公开。 必填项已用 * 标注