You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算连接两个移动点位的矩形四角坐标,适配SFML的sf::Quads绘制需求

适配任意角度的矩形连线实现方案

核心绘制实现

你之前的问题根源是偏移值固定沿xy轴方向,没有适配连线的角度,正确的做法是先计算连线的垂直方向单位向量,再基于该向量生成四个顶点,修改后的draw函数如下:

#include <cmath>

const float STICK_WIDTH = 20.f; // 可自定义调整连线宽度

void Stick::draw(sf::RenderTarget& target, sf::RenderStates states) const {
    sf::VertexArray shape(sf::Quads, 4);
    sf::Vector2f p1Pos = this->p1->getPosition();
    sf::Vector2f p2Pos = this->p2->getPosition();

    // 计算连线方向向量
    float dx = p2Pos.x - p1Pos.x;
    float dy = p2Pos.y - p1Pos.y;
    float length = std::sqrt(dx * dx + dy * dy);

    // 两点重合时跳过绘制避免除以0报错
    if (length < 1.f) return;

    // 计算垂直于连线的单位偏移向量
    float offsetX = (-dy / length) * (STICK_WIDTH / 2);
    float offsetY = (dx / length) * (STICK_WIDTH / 2);

    // 生成适配角度的四个矩形顶点
    shape[0].position = sf::Vector2f(p1Pos.x + offsetX, p1Pos.y + offsetY);
    shape[1].position = sf::Vector2f(p1Pos.x - offsetX, p1Pos.y - offsetY);
    shape[2].position = sf::Vector2f(p2Pos.x - offsetX, p2Pos.y - offsetY);
    shape[3].position = sf::Vector2f(p2Pos.x + offsetX, p2Pos.y + offsetY);

    // 统一设置颜色
    for (int i = 0; i < 4; i++) {
        shape[i].color = sf::Color::Green;
    }

    target.draw(shape, states);
}

点击检测兼容方案

可以通过计算点击点到连线的垂直距离,结合投影范围判断是否命中Stick,示例实现如下:

bool Stick::contains(sf::Vector2f clickPos) const {
    sf::Vector2f p1Pos = this->p1->getPosition();
    sf::Vector2f p2Pos = this->p2->getPosition();

    float dx = p2Pos.x - p1Pos.x;
    float dy = p2Pos.y - p1Pos.y;
    float lengthSq = dx * dx + dy * dy;

    // 两点重合时无命中
    if (lengthSq < 1.f) return false;

    // 计算点击点在连线上的投影比例,超出两点范围则无命中
    float t = ((clickPos.x - p1Pos.x) * dx + (clickPos.y - p1Pos.y) * dy) / lengthSq;
    if (t < 0.f || t > 1.f) return false;

    // 计算点击点到连线的垂直距离,小于宽度一半则命中
    float cross = std::abs(dx * (clickPos.y - p1Pos.y) - dy * (clickPos.x - p1Pos.x));
    float distance = cross / std::sqrt(lengthSq);
    return distance < STICK_WIDTH / 2;
}

在鼠标点击事件回调中调用contains函数传入鼠标坐标,返回true即可执行删除逻辑。

内容的提问来源于stack exchange,提问作者randomprogramming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:24:00