public PolyEdge(QPointF startPos, LineSide side) { StartPos = startPos; StartSide = side; Next = null; Prev = null; DistOnLine = (0.0f); IsSrcEdge = (false); IsDstEdge = (false); Visited = (false); }
// find if a point is in a line public bool pointInLine(QPointF p, QLineF line) { double AB = Math.Abs(line.p1().point.GetDistance(line.p2().point)); double AP = Math.Abs(p.point.GetDistance(line.p1().point)); double PB = Math.Abs(p.point.GetDistance(line.p2().point)); if (Math.Abs(AB - (AP + PB)) < 1.0) { return(true); } else { return(false); } }
// public PointLatLng FindLineIntersection(PointLatLng start1, PointLatLng end1, PointLatLng start2, PointLatLng end2) public QPointF intersect(QLineF otherLine) { PointLatLng start1 = point1.point; PointLatLng end1 = point2.point; PointLatLng start2 = otherLine.point1.point; PointLatLng end2 = otherLine.point2.point; double denom = ((end1.Lng - start1.Lng) * (end2.Lat - start2.Lat)) - ((end1.Lat - start1.Lat) * (end2.Lng - start2.Lng)); // AB & CD are parallel if (denom == 0) { return(null); } double numer = ((start1.Lat - start2.Lat) * (end2.Lng - start2.Lng)) - ((start1.Lng - start2.Lng) * (end2.Lat - start2.Lat)); double r = numer / denom; double numer2 = ((start1.Lat - start2.Lat) * (end1.Lng - start1.Lng)) - ((start1.Lng - start2.Lng) * (end1.Lat - start1.Lat)); double s = numer2 / denom; if ((r < 0 || r > 1) || (s < 0 || s > 1)) { return(null); } // Find intersection point QPointF result = new QPointF(PointLatLng.Empty); result.point.Lng = start1.Lng + (r * (end1.Lng - start1.Lng)); result.point.Lat = start1.Lat + (r * (end1.Lat - start1.Lat)); // delete intersect no in split line if (!pointInLine(result, otherLine)) { return(null); } return(result); }
// only support pairs split points List <QPolygonF> SplitEdges2(QPolygonF poly, QLineF line) { if (SplitPoly != null) { SplitPoly.Clear(); } if (EdgesOnLine != null) { EdgesOnLine.Clear(); } // line = new QLineF(new QPointF(new PointLatLngAlt(31.840743072180324, 121.46284818649292)), new QPointF(new PointLatLngAlt(31.840615471377312 , 121.46491885185242))); for (int i = 0; i < (poly.Count); i++) { QLineF edge = new QLineF(poly.ElementAtOrDefault(i), poly.ElementAtOrDefault((i + 1) % poly.Count)); LineSide edgeStartSide = GetSideOfLine(line, edge.p1()); LineSide edgeEndSide = GetSideOfLine(line, edge.p2()); SplitPoly.Add(new PolyEdge(poly[i], edgeStartSide)); // SplitPoly.push_back(PolyEdge{ poly[i], edgeStartSide}); // if (edgeStartSide == LineSide.On) // { // EdgesOnLine.Add(SplitPoly.LastOrDefault()); // // EdgesOnLine.push_back(&SplitPoly.back()); // } // else if (!edgeStartSide.Equals(edgeEndSide) && edgeEndSide != LineSide.On) if (!edgeStartSide.Equals(edgeEndSide) && edgeEndSide != LineSide.On) { QPointF ip; ip = edge.intersect(line); // assert(res != QLineF::NoIntersection); if (ip != null) { SplitPoly.Add(new PolyEdge(ip, LineSide.On)); // SplitPoly.push_back(PolyEdge{ ip, LineSide::On}); EdgesOnLine.Add(SplitPoly.LastOrDefault()); // EdgesOnLine.Add(&SplitPoly.back()); } } } int poly_in_split_pair = 0; List <QPointF> split_pair = new List <QPointF>(); List <QPolygonF> resPolys = new List <QPolygonF>(); // connect doubly linked list and split it into pieces poly // first->prev and last->next QPolygonF split_out = new QPolygonF(); QPointF start_point = new QPointF(new PointLatLng()); QPointF end_point = new QPointF(new PointLatLng()); int ii = 0; for (ii = 0; ii < (SplitPoly.Count); ii++) // .begin(); iter!=std::prev(SplitPoly.end()); iter++) // for (auto iter = SplitPoly.begin(); iter != std::prev(SplitPoly.end()); iter++) { if (SplitPoly.ElementAtOrDefault(ii).StartSide != LineSide.On) // normal points { QPointF qp_added = new QPointF(new PointLatLng(SplitPoly.ElementAtOrDefault(ii).StartPos.x(), SplitPoly.ElementAtOrDefault(ii).StartPos.y())); split_out.Add(qp_added); } else // edge points { if (0 == (poly_in_split_pair %= 2)) // new start point, then find out the end point { poly_in_split_pair = 0; QPolygonF split_out2 = new QPolygonF(); // 2nd poly // add start point start_point = new QPointF(new PointLatLng(SplitPoly.ElementAtOrDefault(ii).StartPos.x(), SplitPoly.ElementAtOrDefault(ii).StartPos.y())); split_out.Add(start_point); split_out2.Add(start_point); // find next split point to 1st poly // SplitPoly.ElementAtOrDefault(ii - 1).Next = SplitPoly.ElementAtOrDefault(ii); bool collect_pnt = false; for (int jj = ii + 1; jj < (SplitPoly.Count); jj++) // .begin(); iter!=std::prev(SplitPoly.end()); iter++) { if (collect_pnt) { QPointF qp_added = new QPointF(new PointLatLng(SplitPoly.ElementAtOrDefault(jj).StartPos.x(), SplitPoly.ElementAtOrDefault(jj).StartPos.y())); split_out.Add(qp_added); } else if (SplitPoly.ElementAtOrDefault(jj).StartSide == LineSide.On) // end points { end_point = new QPointF(new PointLatLng(SplitPoly.ElementAtOrDefault(jj).StartPos.x(), SplitPoly.ElementAtOrDefault(jj).StartPos.y())); split_out.Add(end_point); // split_out2.Add(qp_added); collect_pnt = true; } else // 2nd poly { QPointF qp_added = new QPointF(new PointLatLng(SplitPoly.ElementAtOrDefault(jj).StartPos.x(), SplitPoly.ElementAtOrDefault(jj).StartPos.y())); split_out2.Add(qp_added); } } resPolys.Add(split_out); split_out2.Add(end_point); resPolys.Add(split_out2); start_point = new QPointF(new PointLatLng()); end_point = new QPointF(new PointLatLng()); split_out = new QPolygonF(); split_out2 = new QPolygonF(); } poly_in_split_pair++; } // auto nextIter = std::next(iter); // iter.Next = nextIter; // nextIter->Prev = &(* iter); } // add last poly // resPolys.Add(split_out); return(resPolys); }
public QLineF(QPointF pnt1, QPointF pnt2) { point1 = pnt1; point2 = pnt2; }
static double CalcSignedDistance(QLineF line, 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())); }
static double PointDistance(QPointF pt0, QPointF pt1) { return(pt0.getDistance(pt1)); }
static LineSide GetSideOfLine(QLineF line, QPointF pt) { double d = (pt.x() - line.p1().x()) * (line.p2().y() - line.p1().y()) - (pt.y() - line.p1().y()) * (line.p2().x() - line.p1().x()); return((Math.Sign(d) >= 0) ? LineSide.Right : ((Math.Sign(d) < 0) ? LineSide.Left : LineSide.On)); }
public double getDistance(QPointF pnt) { return(point.GetDistance(pnt.point)); }