// 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); } }
void SplitEdges(QPolygonF poly, QLineF line) { if (SplitPoly != null) { SplitPoly.Clear(); } if (EdgesOnLine != null) { EdgesOnLine.Clear(); } 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) { 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()); } } } // connect doubly linked list, except // first->prev and last->next for (int ii = 0; ii < (SplitPoly.Count - 1); ii++) // .begin(); iter!=std::prev(SplitPoly.end()); iter++) // for (auto iter = SplitPoly.begin(); iter != std::prev(SplitPoly.end()); iter++) { SplitPoly.ElementAtOrDefault(ii).Next = SplitPoly.ElementAtOrDefault(ii + 1); SplitPoly.ElementAtOrDefault(ii + 1).Prev = SplitPoly.ElementAtOrDefault(ii); // auto nextIter = std::next(iter); // iter.Next = nextIter; // nextIter->Prev = &(* iter); } // connect first->prev and last->next SplitPoly.LastOrDefault().Next = SplitPoly.FirstOrDefault(); SplitPoly.FirstOrDefault().Prev = SplitPoly.LastOrDefault(); // SplitPoly.back().Next = &SplitPoly.front(); // SplitPoly.front().Prev = &SplitPoly.back(); }
// 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); }
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 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)); }