mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-06 11:14:14 +02:00
Wire terminals one after another under a wires-per-terminal limit
Discussion #1158, stacked on the limit itself. Two of QElectroTech's own tools wire several terminals as a star, every terminal to one of them: "create wires in a drawn polygon" (also qet.addConductor()), and deleting a symbol, which rewires the far ends to keep the potential. Six terminals give the hub five wires, which the project's limit forbids. When the project sets a limit (and the master switch is on), both now wire the terminals one after another instead, from the top left one to the nearest not yet wired (WiringRules::chainOrder()). The polygon tool also skips a wire whose terminal is already full. Without a limit, both build the star as before. tst_wiringrules: the chain order, and through the real binary that deleting a symbol wired to four others leaves them with at most two wires each under a limit, three on one of them without (checked to fail with chaining turned off). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015FPuYPS4T7QuEwjNu22rXD
This commit is contained in:
@@ -124,3 +124,65 @@ bool WiringRules::hasRoom(int limit, int wires)
|
||||
{
|
||||
return limit <= 0 || wires < limit;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::chainsWires
|
||||
@return true if QElectroTech's own tools that wire several terminals at
|
||||
once must wire them one after another (a chain) rather than all to one
|
||||
of them (a star): a star gives that one terminal a wire per other
|
||||
terminal, which the project's limit forbids.
|
||||
*/
|
||||
bool WiringRules::chainsWires(const Settings &settings, bool master_enabled)
|
||||
{
|
||||
return master_enabled && settings.max_wires > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief WiringRules::chainOrder
|
||||
The order in which to wire terminals at \a points one after another:
|
||||
from the top left one (smallest x, then smallest y, the same terminal
|
||||
the star used as its hub), each time to the nearest terminal not yet
|
||||
wired. Distance is along the grid (|dx| + |dy|), since wires run
|
||||
horizontally and vertically; a tie goes to the earlier point.
|
||||
@return indexes into \a points, each once
|
||||
*/
|
||||
QList<int> WiringRules::chainOrder(const QList<QPointF> &points)
|
||||
{
|
||||
QList<int> order;
|
||||
if (points.isEmpty()) {
|
||||
return order;
|
||||
}
|
||||
|
||||
int current = 0;
|
||||
for (int i = 1 ; i < points.size() ; ++i) {
|
||||
const QPointF &p = points.at(i);
|
||||
const QPointF &c = points.at(current);
|
||||
if (p.x() < c.x() || (p.x() == c.x() && p.y() < c.y())) {
|
||||
current = i;
|
||||
}
|
||||
}
|
||||
|
||||
QList<bool> done(points.size(), false);
|
||||
order << current;
|
||||
done[current] = true;
|
||||
while (order.size() < points.size())
|
||||
{
|
||||
int nearest = -1;
|
||||
qreal nearest_distance = 0;
|
||||
for (int i = 0 ; i < points.size() ; ++i) {
|
||||
if (done.at(i)) {
|
||||
continue;
|
||||
}
|
||||
const QPointF d = points.at(i) - points.at(current);
|
||||
const qreal distance = qAbs(d.x()) + qAbs(d.y());
|
||||
if (nearest < 0 || distance < nearest_distance) {
|
||||
nearest = i;
|
||||
nearest_distance = distance;
|
||||
}
|
||||
}
|
||||
order << nearest;
|
||||
done[nearest] = true;
|
||||
current = nearest;
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user