public void Test_Dx_Dy() { var s = new QLineF(5.0, 5.0, 10.0, 10.0); Assert.AreEqual(5.0, s.Dx); Assert.AreEqual(5.0, s.Dy); }
public void TestNotEqualOperator() { var s1 = new QLineF(5.0, 5.0, 10.0, 10.0); var s2 = new QLineF(5.0, 5.0, 15.0, 10.0); Assert.AreNotEqual(s1, s2); }
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(); }
public void TestIsNull() { using (var s = new QLineF(5.0, 5.0, 10.0, 10.0)) { Assert.IsFalse(s.IsNull); } }
// ----------------------------------------------------------------------- public List <QPolygonF> Split(QPolygonF poly, QLineF line) { SplitEdges(poly, line); SortEdges(line); SplitPolygon(); return(CollectPolys()); }
public void TestEqualOperator() { var s1 = new QLineF(5.0, 5.0, 10.0, 10.0); var s2 = new QLineF(5.0, 5.0, 10.0, 10.0); Assert.AreEqual(s1, s2); }
void SortEdges(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); * });*/ // TODO: ?? to confirm EdgesOnLine.Sort((x, y) => (CalcSignedDistance(line, x.StartPos).CompareTo(CalcSignedDistance(line, y.StartPos)))); // compute distance between each edge's start // position and the first edge's start position for (int i = 1; i < EdgesOnLine.Count; i++) { EdgesOnLine.ElementAtOrDefault(i).DistOnLine = PointDistance(EdgesOnLine.ElementAtOrDefault(i).StartPos, EdgesOnLine.ElementAtOrDefault(0).StartPos); } // EdgesOnLine[i]->DistOnLine = PointDistance(EdgesOnLine[i]->StartPos, EdgesOnLine[0]->StartPos); }
public void TestNotEqualOperator() { using (var s1 = new QLineF(5.0, 5.0, 10.0, 10.0)) { using (var s2 = new QLineF(5.0, 5.0, 15.0, 10.0)) { Assert.AreNotEqual(s1, s2); } } }
public void Test_X1_Y1_X2_Y2() { var s = new QLineF(5.0, 5.0, 10.0, 10.0); Assert.AreEqual(5.0, s.X1); Assert.AreEqual(5.0, s.Y1); Assert.AreEqual(10.0, s.X2); Assert.AreEqual(10.0, s.Y2); }
public void TestPoints() { var s = new QLineF(new QPointF(5.0, 5.0), new QPointF(10.0, 10.0)); Assert.AreEqual(5.0, s.P1.X); Assert.AreEqual(5.0, s.P1.Y); Assert.AreEqual(10.0, s.P2.X); Assert.AreEqual(10.0, s.P2.Y); }
public void TestIntConstructor() { var s = new QLineF(5.0, 5.0, 10.0, 10.0); Assert.AreEqual(5.0, s.X1); Assert.AreEqual(5.0, s.Y1); Assert.AreEqual(10.0, s.X2); Assert.AreEqual(10.0, s.Y2); }
public void TestPointsConstructor() { var s = new QLineF(new QPointF(5.0, 5.0), new QPointF(10.0, 10.0)); Assert.AreEqual(5.0, s.X1); Assert.AreEqual(5.0, s.Y1); Assert.AreEqual(10.0, s.X2); Assert.AreEqual(10.0, s.Y2); }
public void TestEqualOperator() { using (var s1 = new QLineF(5.0, 5.0, 10.0, 10.0)) { using (var s2 = new QLineF(5.0, 5.0, 10.0, 10.0)) { Assert.AreEqual(s1, s2); } } }
public void TestTranslatedWithInt() { var s = new QLineF(5.0, 5.0, 10.0, 10.0); var res = s.Translated(5.0, 5.0); Assert.AreEqual(10.0, res.X1); Assert.AreEqual(10.0, res.Y1); Assert.AreEqual(15.0, res.X2); Assert.AreEqual(15.0, res.Y2); }
public void TestTranslateWithInt() { var s = new QLineF(5.0, 5.0, 10.0, 10.0); s.Translate(5, 5); Assert.AreEqual(10.0, s.X1); Assert.AreEqual(10.0, s.Y1); Assert.AreEqual(15.0, s.X2); Assert.AreEqual(15.0, s.Y2); }
public void TestSetLine() { var s = new QLineF(); s.SetLine(5.0, 5.0, 10.0, 10.0); Assert.AreEqual(5.0, s.X1); Assert.AreEqual(5.0, s.Y1); Assert.AreEqual(10.0, s.X2); Assert.AreEqual(10.0, s.Y2); }
public void TestTranslateWithPoint() { using (var s = new QLineF(5.0, 5.0, 10.0, 10.0)) { s.Translate(new QPointF(5.0, 5.0)); Assert.AreEqual(10.0, s.X1); Assert.AreEqual(10.0, s.Y1); Assert.AreEqual(15.0, s.X2); Assert.AreEqual(15.0, s.Y2); } }
public void TestSetPoints() { var s = new QLineF(); var p1 = new QPointF(5.0, 5.0); var p2 = new QPointF(10.0, 10.0); s.SetPoints(p1, p2); Assert.AreEqual(5.0, s.P1.X); Assert.AreEqual(5.0, s.P1.Y); Assert.AreEqual(10.0, s.P2.X); Assert.AreEqual(10.0, s.P2.Y); }
// 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 void TestTranslatedWithPoint() { QLineF res; using (var s = new QLineF(5.0, 5.0, 10.0, 10.0)) { res = s.Translated(new QPointF(5.0, 5.0)); } Assert.AreEqual(10.0, res.X1); Assert.AreEqual(10.0, res.Y1); Assert.AreEqual(15.0, res.X2); Assert.AreEqual(15.0, res.Y2); }
// 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); }
/// <summary> /// Calculates intersection - if any - of two lines /// </summary> /// <param name="otherLine"></param> /// <returns>Intersection or null</returns> /// <remarks>Taken from http://tog.acm.org/resources/GraphicsGems/gemsii/xlines.c </remarks> public QPointF intersect(QLineF otherLine) { var a1 = point2.y() - point1.y(); // var a1 = Y2 - Y1; var b1 = point1.x() - point2.x(); // var b1 = X1 - X2; var c1 = point2.x() * point1.y() - point1.x() * point2.y(); // var c1 = X2 * Y1 - X1 * Y2; /* Compute r3 and r4. */ var r3 = a1 * otherLine.point1.x() + b1 * otherLine.point1.y() + c1; var r4 = a1 * otherLine.point2.x() + b1 * otherLine.point2.y() + c1; // var r3 = a1 * otherLine.X1 + b1 * otherLine.Y1 + c1; // var r4 = a1 * otherLine.X2 + b1 * otherLine.Y2 + c1; /* Check signs of r3 and r4. If both point 3 and point 4 lie on * same side of line 1, the line segments do not intersect. */ if (r3 != 0 && r4 != 0 && Math.Sign(r3) == Math.Sign(r4)) { return(null); // DONT_INTERSECT } /* Compute a2, b2, c2 */ var a2 = otherLine.point2.y() - otherLine.point1.y(); var b2 = otherLine.point1.x() - otherLine.point2.x(); var c2 = otherLine.point2.x() * otherLine.point1.y() - otherLine.point1.x() * otherLine.point2.y(); // var a2 = otherLine.Y2 - otherLine.Y1; // var b2 = otherLine.X1 - otherLine.X2; // var c2 = otherLine.X2 * otherLine.Y1 - otherLine.X1 * otherLine.Y2; /* Compute r1 and r2 */ var r1 = a2 * point1.x() + b2 * point1.y() + c2; var r2 = a2 * point2.x() + b2 * point2.y() + c2; // var r1 = a2 * X1 + b2 * Y1 + c2; // var r2 = a2 * X2 + b2 * Y2 + c2; /* Check signs of r1 and r2. If both point 1 and point 2 lie * on same side of second line segment, the line segments do * not intersect. */ if (r1 != 0 && r2 != 0 && Math.Sign(r1) == Math.Sign(r2)) { return(null); // DONT_INTERSECT } /* Line segments intersect: compute intersection point. */ var denom = a1 * b2 - a2 * b1; if (denom == 0) { return(null); //( COLLINEAR ); } var offset = denom < 0 ? -denom / 2 : denom / 2; /* The denom/2 is to get rounding instead of truncating. It * is added or subtracted to the numerator, depending upon the * sign of the numerator. */ var num = b1 * c2 - b2 * c1; var x = (num < 0 ? num - offset : num + offset) / denom; num = a2 * c1 - a1 * c2; var y = (num < 0 ? num - offset : num + offset) / denom; return(new QPointF(new PointLatLngAlt(x, 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)); }
public void Test_X1_Y1_X2_Y2() { using (var s = new QLineF(5.0, 5.0, 10.0, 10.0)) { Assert.AreEqual(5.0, s.X1); Assert.AreEqual(5.0, s.Y1); Assert.AreEqual(10.0, s.X2); Assert.AreEqual(10.0, s.Y2); } }
public void Test_Dx_Dy() { using (var s = new QLineF(5.0, 5.0, 10.0, 10.0)) { Assert.AreEqual(5.0, s.Dx); Assert.AreEqual(5.0, s.Dy); } }
public void TestEmptyConstructor() { var s = new QLineF(); }
public void TestSetLine() { using (var s = new QLineF()) { s.SetLine(5.0, 5.0, 10.0, 10.0); Assert.AreEqual(5.0, s.X1); Assert.AreEqual(5.0, s.Y1); Assert.AreEqual(10.0, s.X2); Assert.AreEqual(10.0, s.Y2); } }
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())); }
public List <QPolygonF> Split2(QPolygonF poly, QLineF line) { return(SplitEdges2(poly, line));; }
// 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 void TestIsNull() { var s = new QLineF(5.0, 5.0, 10.0, 10.0); Assert.IsFalse(s.IsNull); }
public void TestSetPoints() { using (var s = new QLineF()) { var p1 = new QPointF(5.0, 5.0); var p2 = new QPointF(10.0, 10.0); s.SetPoints(p1, p2); Assert.AreEqual(5.0, s.P1.X); Assert.AreEqual(5.0, s.P1.Y); Assert.AreEqual(10.0, s.P2.X); Assert.AreEqual(10.0, s.P2.Y); } }
public void TimerEvent(QTimerEvent e) { // Don't move too far away QLineF lineToCenter = new QLineF(new QPointF(0, 0), MapFromScene(0, 0)); if (lineToCenter.Length() > 150) { double angleToCenter = Math.Acos(lineToCenter.Dx() / lineToCenter.Length()); if (lineToCenter.Dy() < 0) { angleToCenter = TwoPi - angleToCenter; } angleToCenter = NormalizeAngle((Pi - angleToCenter) + Pi / 2); if (angleToCenter < Pi && angleToCenter > Pi / 4) { // Rotate left angle += (angle < -Pi / 2) ? 0.25 : -0.25; } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) { // Rotate right angle += (angle < Pi / 2) ? 0.25 : -0.25; } } else if (Math.Sin(angle) < 0) { angle += 0.25; } else if (Math.Sin(angle) > 0) { angle -= 0.25; } // Try not to crash with any other mice List <QPointF> list = new List <QPointF>(); list.Add(MapToScene(0, 0)); list.Add(MapToScene(-30, -50)); list.Add(MapToScene(30, -50)); List <IQGraphicsItem> dangerMice = Scene().Items(new QPolygonF(list)); foreach (QGraphicsItem item in dangerMice) { if (item == this) { continue; } QLineF lineToMouse = new QLineF(new QPointF(0, 0), MapFromItem(item, 0, 0)); double angleToMouse = Math.Acos(lineToMouse.Dx() / lineToMouse.Length()); if (lineToMouse.Length() == 0) { angleToMouse = 0; } if (lineToMouse.Dy() < 0) { angleToMouse = TwoPi - angleToMouse; } angleToMouse = NormalizeAngle((Pi - angleToMouse) + Pi / 2); if (angleToMouse >= 0 && angleToMouse < Pi / 2) { // Rotate right angle += 0.5; } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) { // Rotate left angle -= 0.5; } } // Add some random movement if (dangerMice.Count > 1 && (random.Next(10)) == 0) { if (random.Next(1) == 1) { angle += (random.Next(100)) / 500.0; } else { angle -= (random.Next(100)) / 500.0; } } speed += (-50 + random.Next(100)) / 100.0; double dx = Math.Sin(angle) * 10; mouseEyeDirection = (Math.Abs(dx / 5) < 1) ? 0 : dx / 5; Rotate(dx); SetPos(MapToParent(0, -(3 + Math.Sin(speed) * 3))); }