/// <summary> /// Check if and handle the starting line intersections /// </summary> /// <returns>true: starting line has been crossed for the second time -> curve is finished, false: otherweise</returns> private bool handlePointerMoved_StartingLineX(Point currentPoint) { bool startingLineIntersected = VectorMath.CheckIf2LinesIntersect(mStartingLineCandidateLeftPoint, mStartingLineCandidateRightPoint, mPreviousPoint.Value, currentPoint); if (startingLineIntersected) { // check if we have the right angle, i.e. y coordinates must always get less if ((currentPoint.Y - mPreviousPoint.Value.Y) < 0) { // right direction mNrStartingLineIntersected++; if (mNrStartingLineIntersected == 2) { // we are done the starting line has been intersected in the right direction for the second time CurvePaintingFinished(); return(true); } } else { // wrong direction -> user needs to start drawing from scratch SetInstructionText(true, ERROR_STARTING_LINE_X_WRONG_DIRECTION); mTrackCreationState = trackCreationState.Error; } } return(false); }
/// <summary> /// check if the starting line is crossed and return the direction /// </summary> private bool CheckIfStartingLineIsCrossed(IList <Point> routeGridPoints, Point gridPointClicked, out bool rightDirection) { if (routeGridPoints.Count < 2) { rightDirection = false; // too few return(false); } // determine if we are going in the right direction for the starting line // right direction is from down to up, i.e. from a higher Y-coordinate to a lower rightDirection = routeGridPoints.Last().Y > gridPointClicked.Y; // does the clicked grid point actually lie on the starting line if (IsGridPointOnStartingLine(gridPointClicked)) { // yes it does, return true, no need to check for an intersection return(true); } // for the intersection check we need to extend the starting line beyond the grid points // as the starting line also includes the part which is left of the left grid point // and which is right of the right grid point. Point extendedLeft = new Point(startingLineGridPointLeft.X, startingLineGridPointLeft.Y); if (extendedLeft.X > 0) { extendedLeft.X -= 1; } ; Point extendedRight = new Point(startingLineGridPointRight.X + 1, startingLineGridPointRight.Y); // now check if the car has crossed has the finish line return(VectorMath.CheckIf2LinesIntersect(extendedLeft, extendedRight, routeGridPoints.Last(), gridPointClicked)); }
/// <summary> /// ray casting algorithm /// https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm /// </summary> private static bool Contains(Polygon polygon, Point location) { // nr of intersections uint nrIntersects = 0; Point horizontalLineLeft = new Point(0, location.Y); Point horizontalLineRight = new Point(location.X, location.Y); Point?oldPoint = null; for (int index = 0; index < polygon.Points.Count; index++) { if (oldPoint.HasValue) { // construct Line and do intersection check if (VectorMath.CheckIf2LinesIntersect(horizontalLineLeft, horizontalLineRight, oldPoint.Value, polygon.Points[index])) { nrIntersects++; } } // save for next line oldPoint = polygon.Points[index]; } // first check if the first point of the polygon lies on the starting line // which is the case for random generated polygon tracks // we must not count this point twice... if (polygon.Points[0].Y != location.Y) { // now check the last closing polygon line if (VectorMath.CheckIf2LinesIntersect(horizontalLineLeft, horizontalLineRight, oldPoint.Value, polygon.Points[0])) { nrIntersects++; } } // odd number means inside return(nrIntersects % 2 == 1); }
/// <summary> /// check if 'oneLine' intersects with any line in 'lineColl' /// </summary> /// <param name="oneLine">the line to check for intersections with lineColl</param> /// <param name="lineColl"></param> /// <param name="position">if there is an intersection, this is the index (zero-based) of the first line that intersects</param> /// <returns>true: an intersection was found, false: otherwise</returns> internal static bool CheckIfLineIntersectsWithLineCollection(Line oneLine, IList <Line> lineColl, out int position) { bool intersectionFound = false; position = -1; Point oneLine01 = new Point(oneLine.X1, oneLine.Y1); Point oneLine02 = new Point(oneLine.X2, oneLine.Y2); for (int index = 0; (index < lineColl.Count) && (intersectionFound == false); index++) { Line lineInColl = lineColl[index]; Point lineColl01 = new Point(lineInColl.X1, lineInColl.Y1); Point lineColl02 = new Point(lineInColl.X2, lineInColl.Y2); if (VectorMath.CheckIf2LinesIntersect(oneLine01, oneLine02, lineColl01, lineColl02)) { intersectionFound = true; position = index; } } return(intersectionFound); }