Stack Overflow на русском Asked on November 5, 2021
Нашёл ответ . Но не могу понять как сортирует на C++, как написать аналогичный код на C#?
void PolySplitter::SortEdges(const QLineF &line)
{
// sort edges by start position relative to
// the start position of the split line
std::sort(EdgesOnLine.begin(), EdgesOnLine.end(), [&](PolyEdge *e0, PolyEdge *e1)
{
// it's important to take the signed distance here,
// because it can happen that the split line starts/ends
// inside the polygon. in that case intersection points
// can fall on both sides of the split line and taking
// an unsigned distance metric will result in wrongly
// ordered points in EdgesOnLine.
return CalcSignedDistance(line, e0->StartPos) < CalcSignedDistance(line, e1->StartPos);
});
// compute distance between each edge's start
// position and the first edge's start position
for (size_t i=1; i<EdgesOnLine.size(); i++)
EdgesOnLine[i]->DistOnLine = PointDistance(EdgesOnLine[i]->StartPos, EdgesOnLine[0]->StartPos);
}
Более полная информация по коду на C++:
std::vector<PolyEdge *> EdgesOnLine;
struct PolyEdge
{
PolyEdge(const QPointF &startPos, LineSide side) :
StartPos(startPos),
StartSide(side),
Next(nullptr),
Prev(nullptr),
DistOnLine(0.0f),
IsSrcEdge(false),
IsDstEdge(false),
Visited(false)
{
}
QPointF StartPos; // start position on edge
LineSide StartSide; // start position's side of split line
PolyEdge * Next; // next polygon in linked list
PolyEdge * Prev; // previous polygon in linked list
float DistOnLine; // distance relative to first point on split line
bool IsSrcEdge; // for visualization
bool IsDstEdge; // for visualization
bool Visited; // for collecting split polygons
};
...
void PolySplitter::SortEdges(const QLineF &line)
{
std::sort(EdgesOnLine.begin(), EdgesOnLine.end(), [&](PolyEdge *e0, PolyEdge *e1)
{
return CalcSignedDistance(line, e0->StartPos) < CalcSignedDistance(line, e1->StartPos);
});
for (size_t i=1; i<EdgesOnLine.size(); i++)
EdgesOnLine[i]->DistOnLine = PointDistance(EdgesOnLine[i]->StartPos, EdgesOnLine[0]->StartPos);
}
...
static double CalcSignedDistance(const QLineF &line, const QPointF &p)
{
// scalar projection on line. in case of co-linear
// vectors this is equal to the signed distance.
return (p.x()-line.p1().x())*(line.p2().x()-line.p1().x())+(p.y()-line.p1().y())*(line.p2().y()-line.p1().y());
}
...
У меня код на C#:
static public List<ClippingOFArbitraryPolygons.PolyEdge> EdgesOnLine;
public class PolyEdge
{
public Vector2 StartPos; // start position on edge
public LineSide StartSide; // start position's side of split line
public PolyEdge Next; // next polygon in linked list
public PolyEdge Prev; // previous polygon in linked list
public float DistOnLine; // distance relative to first point on split line
public bool IsSrcEdge; // for visualization
public bool IsDstEdge; // for visualization
public bool Visited; // for collecting split polygons
public PolyEdge(Vector2 _startPos, LineSide _side)
{
StartPos = _startPos;
StartSide = _side;
Next = Prev = null;
DistOnLine = 0.0f;
IsSrcEdge = IsDstEdge = Visited = false;
}
};
static double CalcSignedDistance(UnityEngine.Vector2[] _line, Vector2 p)
{
// scalar projection on line. in case of co-linear
// vectors this is equal to the signed distance.
return (p.x - _line[0].x) * (_line[1].x - _line[0].x) + (p.y - _line[0].y) * (_line[1].y - _line[0].y);
}
List<ClippingOFArbitraryPolygons.PolyEdge> EdgesOnLine;
Пока не проверил но вот что получилось:
public class PolyEdge : IEquatable<PolyEdge>, IComparable<PolyEdge>
{
public Vector2 StartPos; // start position on edge
public LineSide StartSide; // start position's side of split line
public PolyEdge Next; // next polygon in linked list
public PolyEdge Prev; // previous polygon in linked list
public float DistOnLine; // distance relative to first point on split line
public bool IsSrcEdge; // for visualization
public bool IsDstEdge; // for visualization
public bool Visited; // for collecting split polygons
public int PartId;
public PolyEdge(Vector2 _startPos, LineSide _side)
{
StartPos = _startPos;
StartSide = _side;
Next = Prev = null;
DistOnLine = 0.0f;
IsSrcEdge = IsDstEdge = Visited = false;
}
public int CompareTo(PolyEdge comparePart)
{
return this.PartId.CompareTo(comparePart.PartId);
}
public int CompareTo(PolyEdge comparePart, UnityEngine.Vector2[] _line)
{
if (CalcSignedDistance(_line, this.StartPos) < CalcSignedDistance(_line, comparePart.StartPos))
{
this.PartId--;
comparePart.PartId++;
}
return CompareTo(comparePart);
}
public override int GetHashCode()
{
return PartId;
}
public bool Equals(PolyEdge other)
{
if (other == null) return false;
return (this.PartId.Equals(other.PartId));
}
};
И теперь вызываем сортировку так :
static internal void SortEdges(UnityEngine.Vector2[] _line)
{
EdgesOnLine.Sort((A, B) => A.CompareTo(B,_line));
for (int i = 1; i < EdgesOnLine.Count; i++)
EdgesOnLine[i].DistOnLine = PointDistance(EdgesOnLine[i].StartPos, EdgesOnLine[0].StartPos);
}
Answered by Ivan Triumphov on November 5, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP