如何计算连接两个移动点位的矩形四角坐标,适配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
相关产品推荐
相关产品推荐

