693 lines
24 KiB
C++
693 lines
24 KiB
C++
#include "graphicsItem/electricConnectLineItem.h"
|
||
#include <QGraphicsScene>
|
||
#include <QPainter>
|
||
#include <QStyleOptionGraphicsItem>
|
||
|
||
ElectricConnectLineItem::ElectricConnectLineItem(QGraphicsItem *parent)
|
||
: GraphicsProjectModelItem(parent)
|
||
{
|
||
initial();
|
||
}
|
||
|
||
ElectricConnectLineItem::ElectricConnectLineItem(const ElectricConnectLineItem& obj)
|
||
: GraphicsProjectModelItem(obj)
|
||
{
|
||
initial();
|
||
m_lstPoints = obj.m_lstPoints;
|
||
}
|
||
|
||
ElectricConnectLineItem::~ElectricConnectLineItem()
|
||
{
|
||
}
|
||
|
||
ElectricConnectLineItem* ElectricConnectLineItem::clone() const
|
||
{
|
||
return new ElectricConnectLineItem(*this);
|
||
}
|
||
|
||
void ElectricConnectLineItem::initial()
|
||
{
|
||
m_boundingRect = QRectF();
|
||
m_pen = QPen(Qt::black);
|
||
m_brush = QBrush(Qt::NoBrush);
|
||
setHandleVisible(false);
|
||
setFunctionHandleIfShow(false);
|
||
setFunctionHandleEnaable(false);
|
||
m_lstPoints.push_back(QPointF()); //起点
|
||
m_lstPoints.push_back(QPointF()); //终点
|
||
_curLine = QPoint();
|
||
}
|
||
|
||
|
||
void ElectricConnectLineItem::setStartPoint(const QPointF& p)
|
||
{
|
||
int n = m_lstPoints.size();
|
||
if(n)
|
||
{
|
||
if(n >2)
|
||
{
|
||
if(m_lstPoints[0].x() == m_lstPoints[1].x()) //相邻点在垂直方向,水平移动,否则垂直移动
|
||
{
|
||
m_lstPoints[1].setX(p.x());
|
||
}
|
||
else
|
||
{
|
||
m_lstPoints[1].setY(p.y());
|
||
}
|
||
}
|
||
m_lstPoints[0] = p;
|
||
}
|
||
}
|
||
void ElectricConnectLineItem::setEndPoint(const QPointF& p)
|
||
{
|
||
int n = m_lstPoints.size();
|
||
if(n)
|
||
{
|
||
if(n >2)
|
||
{
|
||
if(m_lstPoints[n-1].x() == m_lstPoints[n-2].x()) //相邻点在垂直方向,水平移动,否则垂直移动
|
||
{
|
||
m_lstPoints[n-2].setX(p.x());
|
||
}
|
||
else
|
||
{
|
||
m_lstPoints[n-2].setY(p.y());
|
||
}
|
||
}
|
||
m_lstPoints[n-1] = p;
|
||
}
|
||
}
|
||
|
||
QPainterPath ElectricConnectLineItem::shape() const
|
||
{
|
||
QPainterPath path;
|
||
//path.addPath(m_points);
|
||
path.addPath(m_pointsBoundingRect);
|
||
return path;
|
||
}
|
||
|
||
QRectF ElectricConnectLineItem::boundingRect() const
|
||
{
|
||
return m_boundingRect;
|
||
}
|
||
|
||
void ElectricConnectLineItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
|
||
{
|
||
if (option->state & QStyle::State_Selected)
|
||
{
|
||
painter->setPen(Qt::red);
|
||
}
|
||
else
|
||
{
|
||
if(_curMonitorStateEnable){ //当前状态被设置
|
||
painter->setPen(QPen(_curMonitorStateColor));
|
||
}
|
||
else
|
||
painter->setPen(m_pen);
|
||
}
|
||
|
||
painter->setBrush(m_brush);
|
||
|
||
painter->drawPath(m_points);
|
||
}
|
||
|
||
void ElectricConnectLineItem::moveLine(QPointF pos)
|
||
{
|
||
QPointF delta = pos - m_lastPoint;
|
||
if(_curLine.isNull())
|
||
{
|
||
if(m_lstPoints.size() > 1)
|
||
{
|
||
int n = m_lstPoints.size();
|
||
for(int i = 0;i < m_lstPoints.size() -1;++i)
|
||
{
|
||
QPointF p1 = m_lstPoints[i];
|
||
QPointF p2 = m_lstPoints[i+1];
|
||
|
||
if(p1.x() == p2.x() && abs(p1.x() - pos.x()) < 2) //在相同竖线
|
||
{
|
||
if(p1.y() > p2.y())
|
||
{
|
||
if(pos.y() > p2.y() && pos.y() < p1.y()) //在竖线上
|
||
{
|
||
|
||
if(i == 0 ) //起点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.prepend(p1);
|
||
m_lstPoints.prepend(p1);
|
||
|
||
i+=2;
|
||
if(m_lstPoints.size() < 6) //补齐后端
|
||
{
|
||
m_lstPoints.append(m_lstPoints.last());
|
||
}
|
||
}
|
||
if(i+1 == n-1) //终点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.append(p2);
|
||
m_lstPoints.append(p2);
|
||
|
||
m_lstPoints[i+1] = p2;
|
||
if(m_lstPoints.size() < 6) //补齐前端,移动后至少6个点
|
||
{
|
||
m_lstPoints.prepend(m_lstPoints.first());
|
||
i+=1;
|
||
}
|
||
}
|
||
//qDebug() << 1 <<" "<<i;
|
||
_curLine = QPoint(i,1);
|
||
break;
|
||
}
|
||
}
|
||
else if(p1.y() < p2.y())
|
||
{
|
||
if(pos.y() < p2.y() && pos.y() > p1.y()) //在竖线上
|
||
{
|
||
|
||
if(i == 0) //起点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.prepend(p1);
|
||
m_lstPoints.prepend(p1);
|
||
i+=2;
|
||
if(m_lstPoints.size() < 6) //补齐后端
|
||
{
|
||
m_lstPoints.append(m_lstPoints.last());
|
||
}
|
||
}
|
||
if(i+1 == n-1) //终点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.append(p2);
|
||
m_lstPoints.append(p2);
|
||
|
||
m_lstPoints[i+1] = p2;
|
||
if(m_lstPoints.size() < 6) //补齐前端
|
||
{
|
||
m_lstPoints.prepend(m_lstPoints.first());
|
||
i+=1;
|
||
}
|
||
}
|
||
//qDebug() << 2 <<" "<<i;
|
||
_curLine = QPoint(i,1);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if(p1.y() == p2.y() && abs(p1.y() - pos.y()) < 2) //在相同横线
|
||
{
|
||
if(p1.x() > p2.x())
|
||
{
|
||
if(pos.x() > p2.x() && pos.x() < p1.x())
|
||
{
|
||
|
||
if(i == 0) //起点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.prepend(p1);
|
||
m_lstPoints.prepend(p1);
|
||
|
||
i+=2;
|
||
if(m_lstPoints.size() < 6) //补齐后端
|
||
{
|
||
m_lstPoints.append(m_lstPoints.last());
|
||
}
|
||
}
|
||
if(i+1 == n-1) //终点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.append(p2);
|
||
m_lstPoints.append(p2);
|
||
|
||
if(m_lstPoints.size() < 6) //补齐前端,移动后至少6个点
|
||
{
|
||
m_lstPoints.prepend(m_lstPoints.first());
|
||
i+=1;
|
||
}
|
||
}
|
||
//qDebug() << 3 <<" "<<i;
|
||
_curLine = QPoint(i,-1);
|
||
break;
|
||
}
|
||
}
|
||
else if(p1.x() < p2.x())
|
||
{
|
||
if(pos.x() < p2.x() && pos.x() > p1.x())
|
||
{
|
||
|
||
if(i == 0) //起点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.prepend(p1);
|
||
m_lstPoints.prepend(p1);
|
||
|
||
i+=2;
|
||
m_lstPoints[i] = p1;
|
||
if(m_lstPoints.size() < 6) //补齐后端
|
||
{
|
||
m_lstPoints.append(m_lstPoints.last());
|
||
}
|
||
}
|
||
if(i+1 == n-1) //终点是连接点,创建复制点
|
||
{
|
||
m_lstPoints.append(p2);
|
||
m_lstPoints.append(p2);
|
||
|
||
if(m_lstPoints.size() < 6) //补齐前端
|
||
{
|
||
m_lstPoints.prepend(m_lstPoints.first());
|
||
i+=1;
|
||
}
|
||
}
|
||
//qDebug() << 4 <<" "<<i;
|
||
_curLine = QPoint(i,-1);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
int n = _curLine.x();
|
||
//qDebug() << n <<" "<<_curLine.y();
|
||
//if(m_lstPoints.size() > 3)
|
||
{
|
||
|
||
if(_curLine.y() == 1) //竖线
|
||
{
|
||
if(n == 0) //起点是原点
|
||
{
|
||
QPointF p(0,delta.y()); //原点不动
|
||
m_lstPoints[n +1] = m_lstPoints[n +1] + p; //第二个点只竖直移动
|
||
m_lstPoints[n +2] = m_lstPoints[n +2] + p; //第三个点只竖直移动
|
||
}
|
||
else if(n == 1)
|
||
{
|
||
QPointF p(delta.x(),0);
|
||
m_lstPoints[n] += p; //第一个点只水平移动
|
||
m_lstPoints[n +1] += p; //第二个点只水平移动
|
||
}
|
||
else if(n == m_lstPoints.size()-2) //起点是倒数第二个点
|
||
{
|
||
QPointF p(0,delta.y());
|
||
m_lstPoints[n] += p; //起点只上下移动
|
||
m_lstPoints[n-1] += p; //上个点只竖直移动
|
||
}
|
||
else if(n == m_lstPoints.size()-3) //起点是倒数第三个点
|
||
{
|
||
QPointF py(0,delta.y());
|
||
QPointF px(delta.x(),0);
|
||
m_lstPoints[n-1] += py; //上个点只垂直移动
|
||
m_lstPoints[n] += delta; //起点任意动
|
||
m_lstPoints[n+1] += px; //第二个点只水平移动
|
||
}
|
||
else
|
||
{
|
||
m_lstPoints[n -1].setY(m_lstPoints[n ].y());
|
||
m_lstPoints[n] += delta;
|
||
m_lstPoints[n +1] += delta;
|
||
m_lstPoints[n +2].setY(m_lstPoints[n +1].y());
|
||
}
|
||
}
|
||
else //横线
|
||
{
|
||
if(n == 0) //起点是原点
|
||
{
|
||
QPointF p(delta.x(),0); //原点不动
|
||
m_lstPoints[n +1] = m_lstPoints[n +1] + p; //第二个点只水平移动
|
||
m_lstPoints[n +2] = m_lstPoints[n +2] + p; //第三个点只水平移动
|
||
}
|
||
else if(n == 1)
|
||
{
|
||
QPointF p(0,delta.y());
|
||
m_lstPoints[n] = m_lstPoints[n] + p; //第一个点只竖直移动
|
||
m_lstPoints[n +1] = m_lstPoints[n +1] + p; //第二个点只竖直移动
|
||
}
|
||
else if(n == m_lstPoints.size()-2) //起点是倒数第二个点
|
||
{
|
||
QPointF p(delta.x(),0);
|
||
m_lstPoints[n] += p; //起点水平移动
|
||
m_lstPoints[n-1] += p; //上个点只水平移动
|
||
}
|
||
else if(n == m_lstPoints.size()-3) //起点是倒数第三个点
|
||
{
|
||
QPointF py(0,delta.y());
|
||
QPointF px(delta.x(),0);
|
||
m_lstPoints[n-1] += px; //上个点只水平移动
|
||
m_lstPoints[n] += delta; //起点任意动
|
||
m_lstPoints[n+1] += py; //第二个点只上下移动
|
||
}
|
||
else
|
||
{
|
||
m_lstPoints[n -1].setX(m_lstPoints[n].x());
|
||
m_lstPoints[n] += delta;
|
||
m_lstPoints[n +1] += delta;
|
||
m_lstPoints[n +2].setX(m_lstPoints[n +1].x());
|
||
}
|
||
}
|
||
}
|
||
|
||
calculatePath();
|
||
}
|
||
|
||
m_lastPoint = pos;
|
||
}
|
||
|
||
void ElectricConnectLineItem::calculatePath()
|
||
{
|
||
if (m_lstPoints.size() < 2) return;
|
||
|
||
QPointF start = m_lstPoints.first();
|
||
QPointF end = m_lstPoints.last();
|
||
|
||
qDebug() << "\n=== calculatePath ===";
|
||
qDebug() << "Start:" << start << "End:" << end;
|
||
|
||
// 创建新路径
|
||
m_points = QPainterPath();
|
||
m_points.moveTo(start);
|
||
qDebug() << "Initialized path, current position:" << m_points.currentPosition();
|
||
|
||
// 获取元件
|
||
QList<QRectF> components = getComponentCollisionRects();
|
||
qDebug() << "Found" << components.size() << "components";
|
||
|
||
// 检查起点终点距离
|
||
qDebug() << "Distance:" << QLineF(start, end).length();
|
||
|
||
// 如果距离很近,直接连接
|
||
if (QLineF(start, end).length() < 10) {
|
||
qDebug() << "Points are very close, direct connection";
|
||
m_points.lineTo(end);
|
||
} else {
|
||
// 生成路径
|
||
generateAvoidancePath(start, end, components);
|
||
}
|
||
|
||
// 验证路径
|
||
qDebug() << "After generation - Path element count:" << m_points.elementCount();
|
||
qDebug() << "After generation - Current position:" << m_points.currentPosition();
|
||
|
||
if (m_points.elementCount() <= 1) {
|
||
qWarning() << "Path has only" << m_points.elementCount() << "elements! Adding direct line";
|
||
m_points.lineTo(end);
|
||
}
|
||
|
||
// 确保路径结束于终点
|
||
if (m_points.currentPosition() != end) {
|
||
qWarning() << "Path does not end at destination! Adding final segment";
|
||
qDebug() << "Expected end:" << end << "Actual end:" << m_points.currentPosition();
|
||
m_points.lineTo(end);
|
||
}
|
||
|
||
update();
|
||
m_boundingRect = m_points.boundingRect();
|
||
prepareGeometryChange();
|
||
|
||
qDebug() << "Final path bounds:" << m_boundingRect;
|
||
qDebug() << "=== calculatePath end ===\n";
|
||
}
|
||
|
||
// 使用形状进行避障
|
||
void ElectricConnectLineItem::generateAvoidancePath(const QPointF& start, const QPointF& end,
|
||
const QList<QRectF>& components)
|
||
{
|
||
qDebug() << "=== generateAvoidancePath (rectilinear) ===";
|
||
|
||
m_points = QPainterPath();
|
||
m_points.moveTo(start);
|
||
|
||
// 生成候选路径列表,按长度排序
|
||
QMultiMap<double, QList<QPointF>> candidatePaths;
|
||
|
||
// 1. 收集所有可能的直角路径
|
||
collectRectilinearPaths(start, end, components, candidatePaths);
|
||
|
||
// 2. 选择最短的安全路径
|
||
for (auto it = candidatePaths.begin(); it != candidatePaths.end(); ++it) {
|
||
const QList<QPointF>& path = it.value();
|
||
|
||
if (isPathSafe(path, components)) {
|
||
qDebug() << " Selected path with length" << it.key() << ":" << path;
|
||
|
||
// 绘制路径
|
||
for (int i = 1; i < path.size(); i++) {
|
||
m_points.lineTo(path[i]);
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 3. 所有路径都失败,使用强制绕行
|
||
qDebug() << " All rectilinear paths failed, using forced bypass";
|
||
generateForcedRectilinearBypass(start, end, components);
|
||
}
|
||
|
||
// 计算路径长度
|
||
double ElectricConnectLineItem::calculatePathLength(const QList<QPointF>& path)
|
||
{
|
||
double length = 0;
|
||
for (int i = 0; i < path.size() - 1; i++) {
|
||
length += QLineF(path[i], path[i+1]).length();
|
||
}
|
||
return length;
|
||
}
|
||
|
||
|
||
// 单一线段与矩形相交检测
|
||
bool ElectricConnectLineItem::lineIntersectsRect(const QLineF& line, const QRectF& rect)
|
||
{
|
||
// 检查端点是否在矩形内
|
||
if (rect.contains(line.p1()) || rect.contains(line.p2())) {
|
||
return true;
|
||
}
|
||
|
||
// 检查是否与矩形的边相交
|
||
QLineF edges[4] = {
|
||
QLineF(rect.topLeft(), rect.topRight()),
|
||
QLineF(rect.topRight(), rect.bottomRight()),
|
||
QLineF(rect.bottomRight(), rect.bottomLeft()),
|
||
QLineF(rect.bottomLeft(), rect.topLeft())
|
||
};
|
||
|
||
QPointF intersection;
|
||
for (int i = 0; i < 4; i++) {
|
||
if (line.intersects(edges[i], &intersection) == QLineF::BoundedIntersection) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// 辅助方法实现
|
||
bool ElectricConnectLineItem::isSegmentSafe(const QPointF& p1, const QPointF& p2,
|
||
const QList<QRectF>& components)
|
||
{
|
||
QLineF segment(p1, p2);
|
||
|
||
for (const QRectF& component : components) {
|
||
if (segmentPenetratesComponent(segment, component)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool ElectricConnectLineItem::isPathSafe(const QList<QPointF>& path,
|
||
const QList<QRectF>& components)
|
||
{
|
||
for (int i = 0; i < path.size() - 1; i++) {
|
||
if (!isSegmentSafe(path[i], path[i+1], components)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// 检查线段是否穿透元件
|
||
bool ElectricConnectLineItem::segmentPenetratesComponent(const QLineF& segment,
|
||
const QRectF& component)
|
||
{
|
||
// 检查线段端点是否在元件内
|
||
bool p1Inside = component.contains(segment.p1());
|
||
bool p2Inside = component.contains(segment.p2());
|
||
|
||
if (p1Inside && p2Inside) {
|
||
// 线段完全在元件内
|
||
return true;
|
||
}
|
||
|
||
// 获取与元件的交点
|
||
int intersectionCount = 0;
|
||
QLineF edges[4] = {
|
||
QLineF(component.topLeft(), component.topRight()),
|
||
QLineF(component.topRight(), component.bottomRight()),
|
||
QLineF(component.bottomRight(), component.bottomLeft()),
|
||
QLineF(component.bottomLeft(), component.topLeft())
|
||
};
|
||
|
||
QPointF intersection;
|
||
for (int i = 0; i < 4; i++) {
|
||
if (segment.intersects(edges[i], &intersection) == QLineF::BoundedIntersection) {
|
||
intersectionCount++;
|
||
}
|
||
}
|
||
|
||
// 如果线段与元件有2个或更多交点,说明穿透了元件
|
||
return intersectionCount >= 2;
|
||
}
|
||
|
||
// 获取所有元件的总边界
|
||
QRectF ElectricConnectLineItem::getTotalComponentsBounds(const QList<QRectF>& components)
|
||
{
|
||
if (components.isEmpty()) {
|
||
return QRectF();
|
||
}
|
||
|
||
QRectF total = components.first();
|
||
for (int i = 1; i < components.size(); i++) {
|
||
total = total.united(components[i]);
|
||
}
|
||
|
||
return total;
|
||
}
|
||
|
||
// 收集所有可能的直角路径
|
||
void ElectricConnectLineItem::collectRectilinearPaths(const QPointF& start, const QPointF& end,
|
||
const QList<QRectF>& components,
|
||
QMultiMap<double, QList<QPointF>>& paths)
|
||
{
|
||
// 2段路径
|
||
QPointF turn1(start.x(), end.y()); // 水平-垂直
|
||
QPointF turn2(end.x(), start.y()); // 垂直-水平
|
||
|
||
addPathIfRectilinear({start, turn1, end}, paths);
|
||
addPathIfRectilinear({start, turn2, end}, paths);
|
||
|
||
// 3段路径
|
||
double midX = (start.x() + end.x()) / 2;
|
||
double midY = (start.y() + end.y()) / 2;
|
||
|
||
// 水平-垂直-水平
|
||
addPathIfRectilinear({start,
|
||
QPointF(start.x(), midY),
|
||
QPointF(end.x(), midY),
|
||
end}, paths);
|
||
|
||
// 垂直-水平-垂直
|
||
addPathIfRectilinear({start,
|
||
QPointF(midX, start.y()),
|
||
QPointF(midX, end.y()),
|
||
end}, paths);
|
||
|
||
// 4段路径(绕行)
|
||
collectBypassPaths(start, end, components, paths);
|
||
}
|
||
|
||
// 添加路径(如果是直角)
|
||
void ElectricConnectLineItem::addPathIfRectilinear(const QList<QPointF>& path,
|
||
QMultiMap<double, QList<QPointF>>& paths)
|
||
{
|
||
// 检查是否所有线段都是水平或垂直
|
||
for (int i = 0; i < path.size() - 1; i++) {
|
||
if (path[i].x() != path[i+1].x() && path[i].y() != path[i+1].y()) {
|
||
return; // 不是直角
|
||
}
|
||
}
|
||
|
||
double length = calculatePathLength(path);
|
||
paths.insert(length, path);
|
||
}
|
||
|
||
// 收集绕行路径
|
||
void ElectricConnectLineItem::collectBypassPaths(const QPointF& start, const QPointF& end,
|
||
const QList<QRectF>& components,
|
||
QMultiMap<double, QList<QPointF>>& paths)
|
||
{
|
||
if (components.isEmpty()) return;
|
||
|
||
// 获取所有元件的总边界
|
||
QRectF totalBounds = getTotalComponentsBounds(components);
|
||
if (!totalBounds.isValid()) return;
|
||
|
||
const double clearance = 20.0;
|
||
QRectF expanded = totalBounds.adjusted(-clearance, -clearance, clearance, clearance);
|
||
|
||
// 从上方绕行
|
||
addPathIfRectilinear({start,
|
||
QPointF(start.x(), expanded.top()),
|
||
QPointF(end.x(), expanded.top()),
|
||
end}, paths);
|
||
|
||
// 从下方绕行
|
||
addPathIfRectilinear({start,
|
||
QPointF(start.x(), expanded.bottom()),
|
||
QPointF(end.x(), expanded.bottom()),
|
||
end}, paths);
|
||
|
||
// 从左方绕行
|
||
addPathIfRectilinear({start,
|
||
QPointF(expanded.left(), start.y()),
|
||
QPointF(expanded.left(), end.y()),
|
||
end}, paths);
|
||
|
||
// 从右方绕行
|
||
addPathIfRectilinear({start,
|
||
QPointF(expanded.right(), start.y()),
|
||
QPointF(expanded.right(), end.y()),
|
||
end}, paths);
|
||
}
|
||
|
||
// 强制直角绕行
|
||
void ElectricConnectLineItem::generateForcedRectilinearBypass(const QPointF& start, const QPointF& end,
|
||
const QList<QRectF>& components)
|
||
{
|
||
qDebug() << " In generateForcedRectilinearBypass";
|
||
|
||
// 找到阻挡的元件
|
||
QRectF blocking = findFirstBlockingComponent(start, end, components);
|
||
|
||
if (blocking.isValid()) {
|
||
qDebug() << " Blocking component:" << blocking;
|
||
|
||
// 从上方或下方绕过
|
||
const double clearance = 15.0;
|
||
double bypassY = (start.y() < blocking.center().y()) ?
|
||
blocking.top() - clearance : blocking.bottom() + clearance;
|
||
|
||
QList<QPointF> path = {start,
|
||
QPointF(start.x(), bypassY),
|
||
QPointF(end.x(), bypassY),
|
||
end};
|
||
|
||
qDebug() << " Forced bypass path:" << path;
|
||
|
||
for (int i = 1; i < path.size(); i++) {
|
||
m_points.lineTo(path[i]);
|
||
}
|
||
} else {
|
||
// 没有阻挡,使用简单的直角路径
|
||
qDebug() << " No blocking component, using simple orthogonal path";
|
||
QPointF turnPoint = (qAbs(start.x() - end.x()) < qAbs(start.y() - end.y())) ?
|
||
QPointF(end.x(), start.y()) : QPointF(start.x(), end.y());
|
||
|
||
m_points.lineTo(turnPoint);
|
||
m_points.lineTo(end);
|
||
}
|
||
}
|
||
|
||
// 找到第一个阻挡的元件
|
||
QRectF ElectricConnectLineItem::findFirstBlockingComponent(const QPointF& start, const QPointF& end,
|
||
const QList<QRectF>& components)
|
||
{
|
||
QLineF line(start, end);
|
||
|
||
for (const QRectF& rect : components) {
|
||
if (lineIntersectsRect(line, rect)) {
|
||
return rect;
|
||
}
|
||
}
|
||
|
||
return QRectF();
|
||
}
|
||
|