public void VisitEnd(EndType end) { if (m_details.Length > 0) { Reporter.TypeFailed(end.Type, CheckID, m_details); } }
//------------------------------------------------------------------------------ public void AddPaths(List <List <IntPoint> > paths, JoinType joinType, EndType endType) { foreach (List <IntPoint> p in paths) { AddPath(p, joinType, endType); } }
public void VisitEnd(EndType end) { if (m_needsCheck && m_hasBadField) { Reporter.TypeFailed(end.Type, CheckID, m_details); } }
private static ZigZagEval GetZigZagEval <TQuote>( EndType endType, int index, TQuote q) where TQuote : IQuote { ZigZagEval eval = new() { Index = index }; // consider `type` switch (endType) { case EndType.Close: eval.Low = q.Close; eval.High = q.Close; break; case EndType.HighLow: eval.Low = q.Low; eval.High = q.High; break; default: break; } return(eval); }
// Show final window with "Retry" button // and maximum of points you`ve collected public void ShowEndGameWindow(EndType type) { _endWindow.SetActive(true); switch (type) { case EndType.Comleted: _logoText.text = "Completed"; break; case EndType.Failure: _logoText.text = "Game Over"; break; } _maxPointsText.text = _saveController.GetMaxPointValue().ToString(); _yourPointsText.text = _pointController.Points.ToString(); _difficultySlider.interactable = true; _mainController.SetActive(false); var arr = CentipedeController.controllers; foreach (CentipedeController cc in arr) { if (cc != null) { cc.StopAllCoroutines(); } } _saveController.SavePoints(_mainController.GetComponent <PointsController>().Points); }
public void VisitEnd(EndType end) { if (!m_disposable && m_hasDispose) { Reporter.TypeFailed(end.Type, CheckID, string.Empty); } }
protected internal virtual Path FilterStrokePath(Path path, Matrix ctm, float lineWidth, int lineCapStyle, int lineJoinStyle, float miterLimit, LineDashPattern lineDashPattern) { JoinType joinType = GetJoinType(lineJoinStyle); EndType endType = GetEndType(lineCapStyle); if (lineDashPattern != null) { if (IsZeroDash(lineDashPattern)) { return(new Path()); } if (!IsSolid(lineDashPattern)) { path = ApplyDashPattern(path, lineDashPattern); } } ClipperOffset offset = new ClipperOffset(miterLimit, PdfCleanUpProcessor.ArcTolerance * PdfCleanUpProcessor.FloatMultiplier); AddPath(offset, path, joinType, endType); PolyTree resultTree = new PolyTree(); offset.Execute(ref resultTree, lineWidth * PdfCleanUpProcessor.FloatMultiplier / 2); return(FilterFillPath(ConvertToPath(resultTree), ctm, PathPaintingRenderInfo.NONZERO_WINDING_RULE)); }
/// <summary> /// Processes an end of line to determine wether it is part of a folding white space, /// an end of field or an end of header. /// assumes a Carriage return (x0D) has just been read from the "reader". /// </summary> /// <param name="reader">BufferdByteReader to acces the underlying stream</param> /// <returns>Enum EndType</returns> internal async Task<FieldValue.EndType> ProcessEol(BufferedByteReader reader) { var rs = await reader.ReadByteAsync(); if (rs != (byte)FieldValue.SpecialByte.Linefeed) { throw new FormatException("carriagereturn must be followed by linefeed"); } _endType = FieldValue.EndType.EndOfField; // unless folowed by a space ( a folding white space = FWS) rs = await reader.ReadByteAhead(); if (rs == (byte)FieldValue.SpecialByte.Space) { rs = await reader.ReadByteAhead(); while (rs == (byte)FieldValue.SpecialByte.Space) { rs = await reader.ReadByteAhead(); } _endType = FieldValue.EndType.None; // unless folowed by a crlf (End of header) // leave 1 space and the not space character on the buffer if (reader.BufferSize > 2) reader.RemoveFirst(reader.BufferSize - 2); } // Two crlf's with or without spaces in between signify te end of the Header if (rs != (byte)FieldValue.SpecialByte.CarriageReturn) return _endType; reader.Clear(); rs = await reader.ReadByteAsync(); if (rs != (byte)FieldValue.SpecialByte.Linefeed) { throw new FormatException("carriagereturn must be followed by linefeed"); } _endType = EndType.EndOfHeader; return _endType; }
void UpdateScoreByGameEnd(EndType end) { if (end != EndType.PROTEST_OPP) { return; } var avgScorePerWeek = Mathf.RoundToInt((float)Modeler.Game.score / Modeler.Week.weekNumber); var weeksLeft = Consts.Balance.END_WEEK - Modeler.Week.weekNumber; Modeler.Game.score += weeksLeft * avgScorePerWeek; if (PlayServicer.IsAuth) { Rank = -1; PlayGamesPlatform.Instance.ReportScore(Modeler.Game.score, GPGSIds.leaderboard_top_operators, delegate(bool isOk) { if (isOk) { LoadRank(); } }); } }
//------------------------------------------------------------------------------ public void AddPaths(Paths paths, JoinType jt, EndType et) { foreach (Path p in paths) { AddPath(p, jt, et); } }
// calculate brick size private static int GetNewBricks <TQuote>( EndType endType, TQuote q, decimal lastOpen, decimal brickSize) where TQuote : IQuote { switch (endType) { case EndType.Close: return((int)((q.Close - lastOpen) / brickSize)); case EndType.HighLow: // high/low assumption: absolute greater diff wins // --> does not consider close direction decimal hQty = (q.High - lastOpen) / brickSize; decimal lQty = (q.Low - lastOpen) / brickSize; return((int)(Math.Abs(hQty) >= Math.Abs(lQty) ? hQty : lQty)); default: return(0); } }
/// <summary> /// Offset this polyline by the specified amount. /// </summary> /// <param name="offset">The amount to offset.</param> /// <param name="endType">The closure type to use on the offset polygon.</param> /// <param name="tolerance">An optional tolerance.</param> /// <returns>A new closed Polygon offset in all directions by offset from the polyline.</returns> public virtual Polygon[] Offset(double offset, EndType endType, double tolerance = Vector3.EPSILON) { var clipperScale = 1.0 / tolerance; var path = this.ToClipperPath(tolerance); var solution = new List <List <IntPoint> >(); var co = new ClipperOffset(); ClipperLib.EndType clEndType; switch (endType) { case EndType.Butt: clEndType = ClipperLib.EndType.etOpenButt; break; case EndType.ClosedPolygon: clEndType = ClipperLib.EndType.etClosedPolygon; break; case EndType.Square: default: clEndType = ClipperLib.EndType.etOpenSquare; break; } co.AddPath(path, JoinType.jtMiter, clEndType); co.Execute(ref solution, offset * clipperScale); // important, scale also used here var result = new Polygon[solution.Count]; for (var i = 0; i < result.Length; i++) { result[i] = solution[i].ToPolygon(tolerance); } return(result); }
private ModelBaseCore ShowNodeInitialForm(string nodeName, EndType nodeType) { switch (nodeType) { case EndType.PPC: Component_PPCInitForm ppcForm = new Component_PPCInitForm(nodeName); ppcForm.ShowDialog(); if (ppcForm.DialogResult == DialogResult.Yes) { return(ppcForm._ppc); } break; case EndType.FPGA: Component_FPGAInitForm fpgaForm = new Component_FPGAInitForm(nodeName); fpgaForm.ShowDialog(); if (fpgaForm.DialogResult == DialogResult.Yes) { return(fpgaForm._fpga); } break; default: //ComputeNodeType.ZYNQ Component_ZYNQInitForm zynqForm = new Component_ZYNQInitForm(nodeName); zynqForm.ShowDialog(); if (zynqForm.DialogResult == DialogResult.Yes) { return(zynqForm._zynq); } break; } return(null); }
public void VisitEnd(EndType end) { if (m_needsCheck) { m_table.Add(end.Type, m_refs); } }
public void GiveAnswer(int answer) { answer--; // Decrement to fit with zero-based index answerBox.SetActive(false); // If printing answer, do a trick and add the answer to the current dialogueList if (printAnswers == true) { dialogueList.Add(answerList[answer]); answerList.Clear(); endType = EndType.newDialouge; nextDialougeDefault = nextDialogueList[answer]; Next(); if (speakerName.Length > 0) { speakerName = playerName; nameText.text = speakerName; nameBox.SetActive(true); } else { nameBox.SetActive(false); } } else if (nextDialogueList[answer] != null) { if (dialogueLog != null) { dialogueLog.LogText(dialogueList[dialogueIndex], speakerName); dialogueLog.LogText(answerList[answer], playerName); } NextDialogue(nextDialogueList[answer]); } }
public void VisitEnd(EndType type) { if (m_needsCheck && m_foundZero && !m_foundNone) { Reporter.TypeFailed(type.Type, CheckID, string.Empty); } }
public void VisitEnd(EndType end) { if (m_hasAdd && m_hasMinus && !m_hasEquals) { Reporter.TypeFailed(end.Type, CheckID, string.Empty); } }
public virtual void PrintAssociation(string type1, string label1, EndType endType1, string type2, string label2, EndType endType2, string name, int size = 2, LinePattern pattern = LinePattern.Solid) { this.printer.Print(type1); if (!string.IsNullOrEmpty(label1)) { this.printer.PrintFormat(" \"{0}\"", label1); } this.printer.PrintFormat(" {0}{1}{2}", endType1.GetLeftSymbol(), pattern.GetSymbol().Repit(size), endType2.GetRightSymbol()); if (!string.IsNullOrEmpty(label2)) { this.printer.PrintFormat(" \"{0}\"", label2); } this.printer.PrintFormat(" {0}", type2); if (!string.IsNullOrEmpty(name)) { this.printer.PrintFormat(" : {0}", name); } this.printer.PrintLn(); }
public void VisitEnd(EndType end) { if (m_needsCheck && m_foundCompare && !m_foundEquals) { Reporter.TypeFailed(end.Type, CheckID, string.Empty); } }
public void VisitEnd(EndType end) { if (!m_disposable && m_ownsField && m_details.Length > 0) { Reporter.TypeFailed(end.Type, CheckID, "Field: " + m_details); } }
public void playAnim() { GetComponent <Animation>().Play(); setFalseVoyeur(); EndType endType = GameController.endType; switch (endType) { case EndType.Level: next.SetActive(value: true); collect.SetActive(value: false); return; case EndType.Hidden: next.SetActive(value: false); collect.SetActive(value: true); GameMenuController.instance.setGoldAmount(100); PlayerPrefsManager.SetLastPlayedMode(GameMode.NORMAL); return; } next.SetActive(value: false); collect.SetActive(value: true); if (endType == EndType.Set) { GameMenuController.instance.setGoldAmount(25); } else { GameMenuController.instance.setGoldAmount(125); } }
public void VisitEnd(EndType end) { if (m_hasFinalizer && m_hasIntPtrField) { Reporter.TypeFailed(end.Type, CheckID, string.Empty); } }
public void AddPaths(PolygonPath paths, JoinType joinType, EndType endType) { foreach (var p in paths) { AddPath(p, joinType, endType); } }
public RoadNode(bool up, GameObject NW, GameObject ES, EndType top, EndType bottom, Vector2 location, bool used) { this.up = up; blockNW = NW; blockES = ES; endTop = top; endBottom = bottom; this.location = location; if (this.up) { this.angle = 0; } else { this.angle = 90; } GameObject road = GameStateController.Instance.GetComponent <BuildingPrefabWrapper>().road; road.GetComponent <Road_Info>().setLocation((int)location.x, (int)location.y); road.GetComponent <Road_Info>().setUsed(used); GameObject.Instantiate(GameStateController.Instance.GetComponent <BuildingPrefabWrapper>().road, new Vector3((int)(location.x * 2.5f * 10.0f), 0.0f, (int)(location.y * 2.5f * 10.0f)), Quaternion.Euler(new Vector3(0, (int)angle, 0)), null); }
public void SwapEndpoints() { var temp = Start; Start = End; End = temp; // swap the end cap flag as well (but not the corner type) var startHadEndCap = StartType.HasFlag(RoadType.EndCap); var endHadEndCap = EndType.HasFlag(RoadType.EndCap); if (endHadEndCap) { StartType |= RoadType.EndCap; } else { StartType &= ~RoadType.EndCap; } if (startHadEndCap) { EndType |= RoadType.EndCap; } else { EndType &= ~RoadType.EndCap; } }
/// <summary> /// Generates a solid outline of the path. /// </summary> /// <param name="path">the path to outline</param> /// <param name="width">The final width outline</param> /// <param name="jointStyle">The style to render the joints.</param> /// <param name="endCapStyle">The style to render the end caps of open paths (ignored on closed paths).</param> /// <returns>A new path representing the outline.</returns> public static IPath GenerateOutline(this IPath path, float width, JointStyle jointStyle = JointStyle.Square, EndCapStyle endCapStyle = EndCapStyle.Square) { var offset = new ClipperOffset() { MiterLimit = MiterOffsetDelta }; JoinType style = Convert(jointStyle); EndType openEndCapStyle = Convert(endCapStyle); // Pattern can be applied to the path by cutting it into segments IEnumerable <ISimplePath> paths = path.Flatten(); foreach (ISimplePath p in paths) { IReadOnlyList <PointF> vectors = p.Points; var points = new List <IntPoint>(vectors.Count); foreach (Vector2 v in vectors) { points.Add(new IntPoint(v.X * ScalingFactor, v.Y * ScalingFactor)); } EndType type = p.IsClosed ? EndType.etClosedLine : openEndCapStyle; offset.AddPath(points, style, type); } return(ExecuteOutliner(width, offset)); }
public void VisitEnd(EndType end) { if (m_isAbstract && m_hasPublicCtor) { Reporter.TypeFailed(end.Type, CheckID, string.Empty); } }
private void levelEnd() { endType = getEndType(); UnityEngine.Debug.Log(endType); if (game.mode != GameMode.ADVENTURE) { SoundManager.instance.GameWin(); } if (game.mode == GameMode.NORMAL) { if (levelToOpen == -1) { PlayerPrefsManager.SetLevel(PlayerPrefsManager.GetLevel() + 1); PlayerPrefsManager.SetBrilliance(PlayerPrefsManager.GetBrilliance() + 1); PlayerPrefsManager.ResetProHint(); FirebaseController.SendLevelLog(); } else { levelToOpen++; } } Movements.instance.executeWithDelay((Movements.Execute)GameAnimController.instance.niceTexts, 0.7f); if (onGameEnd != null) { onGameEnd(game); } }
private String IdToName(Board board, EndType endtype, BoardLink link, int id) { String chipName = String.Empty; switch (endtype) { case EndType.PPC: chipName = board.PPCList[id].Name; break; case EndType.FPGA: chipName = board.FPGAList[id].Name; break; case EndType.ZYNQ: chipName = board.ZYNQList[id].Name; break; case EndType.SW: chipName = board.SwitchList[id].Type; break; case EndType.VPX: chipName = Enum.GetName(typeof(LinkType), link.LinkType); break; default: break; } return(chipName); }
public void VisitEnd(EndType end) { if (m_needsCheck && !m_correct) { Reporter.TypeFailed(end.Type, CheckID, string.Empty); } }
/// <summary> /// Adds all iText /// <see cref="iText.Kernel.Geom.Subpath"/> /// s of the iText /// <see cref="iText.Kernel.Geom.Path"/> /// to the /// <see cref="ClipperOffset"/> /// object with one /// note: it doesn't add degenerate subpaths. /// </summary> /// <returns> /// /// <see cref="System.Collections.IList{E}"/> /// consisting of all degenerate iText /// <see cref="iText.Kernel.Geom.Subpath"/> /// s of the path. /// </returns> public static IList <Subpath> AddPath(ClipperOffset offset, Path path, JoinType joinType, EndType endType) { IList <Subpath> degenerateSubpaths = new List <Subpath>(); foreach (Subpath subpath in path.GetSubpaths()) { if (subpath.IsDegenerate()) { degenerateSubpaths.Add(subpath); continue; } if (!subpath.IsSinglePointClosed() && !subpath.IsSinglePointOpen()) { EndType et; if (subpath.IsClosed()) { // Offsetting is never used for path being filled et = EndType.CLOSED_LINE; } else { et = endType; } IList <Point> linearApproxPoints = subpath.GetPiecewiseLinearApproximation(); offset.AddPath(new List <IntPoint>(ConvertToLongPoints(linearApproxPoints)), joinType, et); } } return(degenerateSubpaths); }
//------------------------------------------------------------------------------ public void AddPath(List<IntPoint> path, JoinType joinType, EndType endType) { int highI = path.Count - 1; if (highI < 0) return; PolyNode newNode = new PolyNode(); newNode.m_jointype = joinType; newNode.m_endtype = endType; //strip duplicate points from path and also get index to the lowest point ... if (endType == EndType.etClosedLine || endType == EndType.etClosedPolygon) while (highI > 0 && path[0] == path[highI]) highI--; newNode.m_polygon.Capacity = highI + 1; newNode.m_polygon.Add(path[0]); int j = 0, k = 0; for (int i = 1; i <= highI; i++) if (newNode.m_polygon[j] != path[i]) { j++; newNode.m_polygon.Add(path[i]); if (path[i].Y > newNode.m_polygon[k].Y || (path[i].Y == newNode.m_polygon[k].Y && path[i].X < newNode.m_polygon[k].X)) k = j; } if (endType == EndType.etClosedPolygon && j < 2) return; m_polyNodes.AddChild(newNode); //if this path's lowest pt is lower than all the others then update m_lowest if (endType != EndType.etClosedPolygon) return; if (m_lowest.X < 0) m_lowest = new IntPoint(m_polyNodes.ChildCount - 1, k); else { IntPoint ip = m_polyNodes.Childs[(int)m_lowest.X].m_polygon[(int)m_lowest.Y]; if (newNode.m_polygon[k].Y > ip.Y || (newNode.m_polygon[k].Y == ip.Y && newNode.m_polygon[k].X < ip.X)) m_lowest = new IntPoint(m_polyNodes.ChildCount - 1, k); } }
//------------------------------------------------------------------------------ public void AddPaths(List<List<Point>> paths, JoinType joinType, EndType endType, double eps = double.Epsilon) { foreach (var p in paths) { AddPath(p, joinType, endType, eps); } }
public static void CalcCylinderTriangles(int numSlices, int numStacks, float radius, Vector3 startPoint, Vector3 endPoint, bool calcNormals, EndType endType, float endOffSet, out Vector3[] pipePoints, out Vector3[] pipeNormals, out int[] pipeTris, out Vector3[] endPoints1, out Vector3[] endNormals1, out int[] endTris1, out Vector3[] endPoints2, out Vector3[] endNormals2, out int[] endTris2) { // get points for cylinder pipePoints = CalcCyclinderPoints(numSlices, numStacks, radius, startPoint, endPoint); int numTriangles = numSlices * numStacks * 2; // build stacks int vIdx = 0; int pIdx = 0; pipeTris = new int[numTriangles * 3]; int[] pointMulti = new int[pipePoints.Length]; for (int stack = 0; stack < numStacks; stack++) { for (int slice = 0; slice < numSlices; slice++) { // FIXME: Move multi?? pointMulti[pipeTris[vIdx] = pIdx + slice]++; pointMulti[pipeTris[vIdx + 1] = pIdx + slice + 1]++; pointMulti[pipeTris[vIdx + 2] = pIdx + slice + numSlices]++; pointMulti[pipeTris[vIdx + 3] = pIdx + slice]++; pointMulti[pipeTris[vIdx + 4] = pIdx + slice + numSlices]++; pointMulti[pipeTris[vIdx + 5] = pIdx + slice + numSlices - 1]++; vIdx += 6; } pIdx += numSlices; } // ends if (endType == EndType.Flat) { int numEndTriangles = numSlices; endTris1 = new int[numEndTriangles * 3]; endPoints1 = new Vector3[numSlices + 1]; // calc mid points for both ends Vector3 cylinderUV = endPoint - startPoint; cylinderUV.Normalize(); Vector3 endP1 = startPoint - (cylinderUV * endOffSet); Vector3 endP2 = startPoint/*endPoint*/ + (cylinderUV * endOffSet); // copy points for (int point = 0; point < endPoints1.Length - 1; point++) { endPoints1[point] = pipePoints[point]; } endPoints1[endPoints1.Length - 1] = endP1; // first end int triIdx = 0; int endPIdx = endPoints1.Length - 1; for (int point = 0; point < numSlices; point++) { endTris1[triIdx] = endPIdx; endTris1[triIdx + 2] = point; if (point == numSlices - 1) endTris1[triIdx + 1] = 0; else endTris1[triIdx + 1] = point + 1; triIdx += 3; } endTris2 = new int[numEndTriangles * 3]; endPoints2 = new Vector3[numSlices + 1]; // copy points for (int point = 0; point < endPoints2.Length - 1; point++) { endPoints2[point] = pipePoints[point]; } endPoints2[endPoints1.Length - 1] = endP2; // second end for (int point = 0; point < endTris2.Length; point += 3) { endTris2[point] = endTris1[point]; endTris2[point + 1] = endTris1[point + 2]; endTris2[point + 2] = endTris1[point + 1]; } if (calcNormals) { endNormals1 = new Vector3[endPoints1.Length]; int idx = 0; for (int tri = 0; tri < numEndTriangles; tri++) { Vector3 v0 = endPoints1[endTris1[idx]]; Vector3 v1 = endPoints1[endTris1[idx + 2]]; Vector3 v2 = endPoints1[endTris1[idx + 1]]; Vector3 e1 = v1 - v0, e2 = v2 - v0; Vector3 fNormal = Vector3.Normalize(Vector3.Cross(e1, e2)); endNormals1[endTris1[idx]] += fNormal; endNormals1[endTris1[idx + 2]] += fNormal; endNormals1[endTris1[idx + 1]] += fNormal; idx += 3; } for (int point = 0; point < endNormals1.Length - 1; point++) { endNormals1[point] *= 0.5f;//1f / (float)//pointMulti[point]; } endNormals1[endNormals1.Length - 1] *= numSlices; endNormals2 = new Vector3[endPoints2.Length]; Array.Copy(endNormals1, endNormals2, endNormals1.Length); for (int point = 0; point < endNormals1.Length; point++) { endNormals2[point].Z = - endNormals2[point].Z; } //mult = new int[endPoints2.Length]; //idx = 0; //for (int tri = 0; tri < numEndTriangles; tri++) //{ // Vector3 v0 = endPoints2[endTris2[idx]]; // Vector3 v1 = endPoints2[endTris2[idx + 1]]; // Vector3 v2 = endPoints2[endTris2[idx + 2]]; // Vector3 e1 = v1 - v0, e2 = v2 - v0; // Vector3 fNormal = Vector3.Normalize(Vector3.Cross(e1, e2)); // endNormals2[endTris2[idx]] += fNormal; // endNormals2[endTris2[idx + 1]] += fNormal; // endNormals2[endTris2[idx + 2]] += fNormal; // idx += 3; //} //for (int point = 0; point < endNormals2.Length; point++) //{ // endNormals2[point] *= 1f / (float)pointMulti[point]; //} } else { endNormals1 = null; endNormals2 = null; } } else if (endType == EndType.Rounded) { // build start end cup int numEndTriangles = numSlices * 6; endPoints1 = new Vector3[(numSlices * 2) + 1]; // build profile - only heights needed? then maybe scale cylinder outline? Vector2[] profile; CalcArcPointsCCW(3, 1, new Vector2(0, 0), 90, out profile); // extract template to scale from points Vector2[] cylinderTemplate = new Vector2[numSlices]; for (int point = 0; point < numSlices; point++) { cylinderTemplate[point] = new Vector2(pipePoints[point].X, pipePoints[point].Y); } // build points by scale & translate cylinder Vector3[] endPoints = new Vector3[numSlices]; for (int level = 0; level < 1; level++) { float scale = profile[level + 1].X; float translation = endOffSet * -profile[level + 1].Y; int epIdx = level * numSlices; for (int point = 0; point < numSlices; point++) { // scale 'x' & 'y', translate 'z' endPoints[point + epIdx] = new Vector3(cylinderTemplate[point].X * scale, cylinderTemplate[point].Y * scale, translation); } } // calc mid points for both ends Vector3 cylinderUV = endPoint - startPoint; cylinderUV.Normalize(); Vector3 endP1 = startPoint - (cylinderUV * endOffSet); // build points for (int point = 0; point < numSlices; point++) { endPoints1[point] = endPoints[point]; } pIdx = numSlices; for (int point = 0; point < numSlices; point++) { endPoints1[pIdx++] = pipePoints[point]; } endPoints1[endPoints1.Length - 1] = endP1; // flip for other end endPoints2 = new Vector3[endPoints1.Length]; for (int point = 0; point < endPoints2.Length; point++) { endPoints2[point] = endPoints1[point]; endPoints2[point].Z = -endPoints2[point].Z; } // build triangles endTris1 = new int[numEndTriangles * 3]; // top cap int triIdx = 0; int endIdx = endPoints1.Length - 1; for (int point = 0; point < numSlices; point++) { endTris1[triIdx] = endIdx; if (point < numSlices - 1) endTris1[triIdx + 1] = point + 1; else endTris1[triIdx + 1] = 0; endTris1[triIdx + 2] = point; triIdx += 3; } // sections //for (int section = 0; section < 1; section++) //{ for (int point = 0; point < numSlices; point++) { endTris1[triIdx] = point; if (point < numSlices - 1) endTris1[triIdx + 1] = point + numSlices + 1; else endTris1[triIdx + 1] = point + 1; endTris1[triIdx + 2] = point + numSlices; endTris1[triIdx + 3] = point; if (point < numSlices - 1) { endTris1[triIdx + 4] = point + 1; endTris1[triIdx + 5] = point + numSlices + 1; } else { endTris1[triIdx + 4] = 0; endTris1[triIdx + 5] = numSlices; } triIdx += 6; } //} // duplicate for end2 endTris2 = new int[endTris1.Length]; for (int point = 0; point < endTris2.Length; point+=3) { endTris2[point] = endTris1[point]; endTris2[point + 1] = endTris1[point + 2]; endTris2[point + 2] = endTris1[point + 1]; } // calc normals if (calcNormals) { // run multiplicites //int[] multi = new int[endPoints1.Length]; //for (int tri = 0; tri < numEndTriangles * 3; tri += 3) //{ // multi[endTris1[tri]]++; // multi[endTris1[tri + 1]]++; // multi[endTris1[tri + 2]]++; //} // calc normals endNormals1 = new Vector3[endPoints1.Length]; for (int tri = 0; tri < numEndTriangles * 3; tri += 3) { Vector3 v0 = endPoints1[endTris1[tri]]; Vector3 v1 = endPoints1[endTris1[tri + 1]]; Vector3 v2 = endPoints1[endTris1[tri + 2]]; Vector3 e1 = v1 - v0, e2 = v2 - v0; Vector3 fNormal = Vector3.Normalize(Vector3.Cross(e1, e2)); endNormals1[endTris1[tri]] += fNormal; endNormals1[endTris1[tri + 1]] += fNormal; endNormals1[endTris1[tri + 2]] += fNormal; } // normalize for (int normal = 0; normal < endNormals1.Length - 1; normal++) { endNormals1[normal] *= 1f / (float)pointMulti[normal]; } // copy for flipside and invert Z endNormals2 = new Vector3[endNormals1.Length]; Array.Copy(endNormals1, endNormals2, endNormals1.Length); for (int normal = 0; normal < endNormals2.Length; normal++) { endNormals1[normal].Z = -endNormals1[normal].Z; } // NOTE: Does not blend with rest or cylinder - problem? } else { endNormals1 = endNormals2 = null; } } else { endPoints1 = null; endTris1 = null; endNormals1 = null; endPoints2 = null; endTris2 = null; endNormals2 = null; } // calc normals if (calcNormals) { pipeNormals = new Vector3[pipePoints.Length]; int idx = 0; for (int tri=0; tri < numTriangles; tri++) { Vector3 v0 = pipePoints[pipeTris[idx]]; Vector3 v1 = pipePoints[pipeTris[idx + 1]]; Vector3 v2 = pipePoints[pipeTris[idx + 2]]; Vector3 e1 = v1 - v0, e2 = v2 - v0; Vector3 fNormal = Vector3.Normalize(Vector3.Cross(e1, e2)); pipeNormals[pipeTris[idx]] += fNormal; pipeNormals[pipeTris[idx + 1]] += fNormal; pipeNormals[pipeTris[idx + 2]] += fNormal; idx += 3; } for (int point = 0; point < pipeNormals.Length; point++) { pipeNormals[point] *= 1f / (float)pointMulti[point]; } } else { pipeNormals = null; endNormals1 = null; endNormals2 = null; } }
private static void AddPath(ClipperOffset offset, Path path, JoinType joinType, EndType endType) { foreach (Subpath subpath in path.Subpaths) { if (!subpath.IsSinglePointClosed() && !subpath.IsSinglePointOpen()) { EndType et; if (subpath.Closed) { // Offsetting is never used for path being filled et = EndType.etClosedLine; } else { et = endType; } IList<Point2D> linearApproxPoints = subpath.GetPiecewiseLinearApproximation(); offset.AddPath(ConvertToIntPoints(linearApproxPoints), joinType, et); } } }
private PolyOffsetBuilder(IReadOnlyList<IReadOnlyList<IntPoint>> points, List<List<IntPoint>> solution, bool isPolygon, double delta, JoinType jointype, EndType endtype, double limit = 0) { Contract.Requires(points != null); Contract.Requires(solution != null); if (ReferenceEquals(solution, points)) throw new ArgumentException("Input and Output parameters cannot be the same", nameof(solution)); if (delta == 0) return; _p = points; _delta = delta; _rmin = 0.5; if (jointype == JoinType.Miter) { if (limit > 2) _rmin = 2.0 / (limit * limit); limit = 0.25; //just in case endtype == etRound } else { if (limit <= 0) limit = 0.25; else if (limit > Math.Abs(delta)) limit = Math.Abs(delta); } solution.Clear(); for (_i = 0; _i < points.Count; _i++) { var len = points[_i].Count; if (len == 0 || (len < 3 && delta <= 0)) continue; else if (len == 1) { _currentPoly = new List<IntPoint>(); _currentPoly = InternalHelpers.BuildArc(points[_i][0], 0, 2 * Math.PI, delta, limit); solution.Add(_currentPoly); continue; } var forceClose = points[_i][0].Equals(points[_i][len - 1]); if (forceClose) len--; //build normals ... _normals.Clear(); for (var j = 0; j < len - 1; ++j) _normals.Add(points[_i][j].UnitNormal(points[_i][j + 1])); if (isPolygon || forceClose) _normals.Add(points[_i][len - 1].UnitNormal(points[_i][0])); else _normals.Add(_normals[len - 2]); _currentPoly = new List<IntPoint>(); if (isPolygon || forceClose) { _k = len - 1; for (_j = 0; _j < len; ++_j) OffsetPoint(jointype, limit); solution.Add(_currentPoly); if (!isPolygon) { _currentPoly = new List<IntPoint>(); _delta = -_delta; _k = len - 1; for (_j = 0; _j < len; ++_j) OffsetPoint(jointype, limit); _delta = -_delta; _currentPoly.Reverse(); solution.Add(_currentPoly); } } else { _k = 0; for (_j = 1; _j < len - 1; ++_j) OffsetPoint(jointype, limit); IntPoint pt1; if (endtype == EndType.OpenButt) { _j = len - 1; pt1 = new IntPoint(InternalHelpers.Round(points[_i][_j].X + _normals[_j].X * delta), InternalHelpers.Round(points[_i][_j].Y + _normals[_j].Y * delta)); AddPoint(pt1); pt1 = new IntPoint(InternalHelpers.Round(points[_i][_j].X - _normals[_j].X * delta), InternalHelpers.Round(points[_i][_j].Y - _normals[_j].Y * delta)); AddPoint(pt1); } else { _j = len - 1; _k = len - 2; _normals[_j] = new DoublePoint(-_normals[_j].X, -_normals[_j].Y); if (endtype == EndType.OpenSquare) DoSquare(); else DoRound(limit); } //re-build Normals ... for (var j = len - 1; j > 0; j--) { _normals[_j] = new DoublePoint(-_normals[j - 1].X, -_normals[j - 1].Y); } _normals[0] = new DoublePoint(-_normals[1].X, -_normals[1].Y); _k = len - 1; for (_j = _k - 1; _j > 0; --_j) OffsetPoint(jointype, limit); if (endtype == EndType.OpenButt) { pt1 = new IntPoint(InternalHelpers.Round(points[_i][0].X - _normals[0].X * delta), InternalHelpers.Round(points[_i][0].Y - _normals[0].Y * delta)); AddPoint(pt1); pt1 = new IntPoint(InternalHelpers.Round(points[_i][0].X + _normals[0].X * delta), InternalHelpers.Round(points[_i][0].Y + _normals[0].Y * delta)); AddPoint(pt1); } else { _k = 1; if (endtype == EndType.OpenSquare) DoSquare(); else DoRound(limit); } solution.Add(_currentPoly); } } //finally, clean up untidy corners ... var clpr = new Clipper(); clpr.AddPolygons(solution, PolyType.Subject); if (delta > 0) { clpr.Execute(ClipType.Union, solution, PolyFillType.Positive, PolyFillType.Positive); } else { var r = clpr.GetBounds(); var outer = new List<IntPoint>(4) { new IntPoint(r.Left - 10, r.Bottom + 10), new IntPoint(r.Right + 10, r.Bottom + 10), new IntPoint(r.Right + 10, r.Top - 10), new IntPoint(r.Left - 10, r.Top - 10) }; clpr.AddPolygon(outer, PolyType.Subject); clpr.ReverseSolution = true; clpr.Execute(ClipType.Union, solution, PolyFillType.Negative, PolyFillType.Negative); if (solution.Count > 0) solution.RemoveAt(0); } }
public static void Offset(IReadOnlyList<IReadOnlyList<IntPoint>> points, List<List<IntPoint>> solution, bool isPolygon, double delta, JoinType jointype, EndType endtype, double limit = 0) { Contract.Requires(points != null); Contract.Requires(solution != null); //This is ugly as hell! The constructor does all the work, mutates one of it's arguments and returns a useless object (the builder has already been used by this point). // ReSharper disable once ObjectCreationAsStatement new PolyOffsetBuilder(points, solution, isPolygon, delta, jointype, endtype, limit); }
//------------------------------------------------------------------------------ public PolyOffsetBuilder(Polygons pts, Polygons solution, bool isPolygon, double delta, JoinType jointype, EndType endtype, double limit = 0) { //precondition: solution != pts if (delta == 0) { solution = pts; return; } m_p = pts; m_delta = delta; m_rmin = 0.5; if (jointype == JoinType.jtMiter) { if (limit > 2) m_rmin = 2.0 / (limit * limit); limit = 0.25; //just in case endtype == etRound } else { if (limit <= 0) limit = 0.25; else if (limit > Math.Abs(delta)) limit = Math.Abs(delta); } double deltaSq = delta * delta; solution.Clear(); solution.Capacity = pts.Count; for (m_i = 0; m_i < pts.Count; m_i++) { int len = pts[m_i].Count; if (len == 0 || (len < 3 && delta <= 0)) continue; else if (len == 1) { currentPoly = new Polygon(); currentPoly = BuildArc(pts[m_i][0], 0, 2 * Math.PI, delta, limit); solution.Add(currentPoly); continue; } bool forceClose = PointsEqual(pts[m_i][0], pts[m_i][len - 1]); if (forceClose) len--; //build normals ... normals.Clear(); normals.Capacity = len; for (int j = 0; j < len - 1; ++j) normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j + 1])); if (isPolygon || forceClose) normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0])); else normals.Add(new DoublePoint(normals[len - 2])); currentPoly = new Polygon(); if (isPolygon || forceClose) { m_k = len - 1; for (m_j = 0; m_j < len; ++m_j) OffsetPoint(jointype, limit); solution.Add(currentPoly); if (!isPolygon) { currentPoly = new Polygon(); m_delta = -m_delta; m_k = len - 1; for (m_j = 0; m_j < len; ++m_j) OffsetPoint(jointype, limit); m_delta = -m_delta; currentPoly.Reverse(); solution.Add(currentPoly); } } else { m_k = 0; for (m_j = 1; m_j < len - 1; ++m_j) OffsetPoint(jointype, limit); IntPoint pt1; if (endtype == EndType.etButt) { m_j = len - 1; pt1 = new IntPoint((Int64)Round(pts[m_i][m_j].X + normals[m_j].X * delta), (Int64)Round(pts[m_i][m_j].Y + normals[m_j].Y * delta)); AddPoint(pt1); pt1 = new IntPoint((Int64)Round(pts[m_i][m_j].X - normals[m_j].X * delta), (Int64)Round(pts[m_i][m_j].Y - normals[m_j].Y * delta)); AddPoint(pt1); } else { m_j = len - 1; m_k = len - 2; normals[m_j].X = -normals[m_j].X; normals[m_j].Y = -normals[m_j].Y; if (endtype == EndType.etSquare) DoSquare(); else DoRound(limit); } //re-build Normals ... for (int j = len - 1; j > 0; j--) { normals[j].X = -normals[j - 1].X; normals[j].Y = -normals[j - 1].Y; } normals[0].X = -normals[1].X; normals[0].Y = -normals[1].Y; m_k = len - 1; for (m_j = m_k - 1; m_j > 0; --m_j) OffsetPoint(jointype, limit); if (endtype == EndType.etButt) { pt1 = new IntPoint((Int64)Round(pts[m_i][0].X - normals[0].X * delta), (Int64)Round(pts[m_i][0].Y - normals[0].Y * delta)); AddPoint(pt1); pt1 = new IntPoint((Int64)Round(pts[m_i][0].X + normals[0].X * delta), (Int64)Round(pts[m_i][0].Y + normals[0].Y * delta)); AddPoint(pt1); } else { m_k = 1; if (endtype == EndType.etSquare) DoSquare(); else DoRound(limit); } solution.Add(currentPoly); } } //finally, clean up untidy corners ... Clipper clpr = new Clipper(); clpr.AddPolygons(solution, PolyType.ptSubject); if (delta > 0) { clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); } else { IntRect r = clpr.GetBounds(); Polygon outer = new Polygon(4); outer.Add(new IntPoint(r.left - 10, r.bottom + 10)); outer.Add(new IntPoint(r.right + 10, r.bottom + 10)); outer.Add(new IntPoint(r.right + 10, r.top - 10)); outer.Add(new IntPoint(r.left - 10, r.top - 10)); clpr.AddPolygon(outer, PolyType.ptSubject); clpr.ReverseSolution = true; clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative); if (solution.Count > 0) solution.RemoveAt(0); } }
//------------------------------------------------------------------------------ public static Polygons OffsetPolyLines(Polygons lines, double delta, JoinType jointype, EndType endtype, double limit) { Polygons result = new Polygons(); //automatically strip duplicate points because it gets complicated with //open and closed lines and when to strip duplicates across begin-end ... Polygons pts = new Polygons(lines); for (int i = 0; i < pts.Count; ++i) { for (int j = pts[i].Count - 1; j > 0; j--) if (PointsEqual(pts[i][j], pts[i][j - 1])) pts[i].RemoveAt(j); } if (endtype == EndType.etClosed) { int sz = pts.Count; pts.Capacity = sz * 2; for (int i = 0; i < sz; ++i) { Polygon line = new Polygon(pts[i]); line.Reverse(); pts.Add(line); } new PolyOffsetBuilder(pts, result, true, delta, jointype, endtype, limit); } else new PolyOffsetBuilder(pts, result, false, delta, jointype, endtype, limit); return result; }
//------------------------------------------------------------------------------ public void AddPath(IList<Point> path, JoinType joinType, EndType endType, double eps = double.Epsilon) { var highI = path.Count - 1; if (highI < 0) return; var newNode = new PolyNode { JoinType = joinType, EndType = endType, Level = 0 }; //strip duplicate points from path and also get index to the lowest point ... if (endType == EndType.ClosedLine || endType == EndType.ClosedPolygon) { while (highI > 0 && path[0] == path[highI]) { highI--; } } var ctr = newNode.Contour; ctr.Capacity = highI + 1; ctr.Add(path[0]); for (var i = 1; i <= highI; i++) { if (ctr[ctr.Count - 1].DistanceTo(path[i]) > eps) { ctr.Add(path[i]); } } if (endType == EndType.ClosedPolygon && ctr.Count < 3) return; polyNodes.Add(newNode); }
//------------------------------------------------------------------------------ public void AddPaths(List<List<IntPoint>> paths, JoinType joinType, EndType endType) { foreach (List<IntPoint> p in paths) AddPath(p, joinType, endType); }
/** * Adds all subpaths of the path to the {@link ClipperOffset} object with one * note: it doesn't add degenerate subpaths. * * @return {@link java.util.List} consisting of all degenerate subpaths of the path. */ private static IList<Subpath> AddPath(ClipperOffset offset, Path path, JoinType joinType, EndType endType) { IList<Subpath> degenerateSubpaths = new List<Subpath>(); foreach (Subpath subpath in path.Subpaths) { if (subpath.IsDegenerate()) { degenerateSubpaths.Add(subpath); continue; } if (!subpath.IsSinglePointClosed() && !subpath.IsSinglePointOpen()) { EndType et; if (subpath.Closed) { // Offsetting is never used for path being filled et = EndType.etClosedLine; } else { et = endType; } IList<Point2D> linearApproxPoints = subpath.GetPiecewiseLinearApproximation(); offset.AddPath(ConvertToIntPoints(linearApproxPoints), joinType, et); } } return degenerateSubpaths; }
//------------------------------------------------------------------------------ public static Paths OffsetPaths(Paths polys, double delta, JoinType jointype, EndType endtype, double MiterLimit) { Paths out_polys = new Paths(polys.Count); IntPoint botPt = new IntPoint(); IntPoint pt; int botIdx = -1; for (int i = 0; i < polys.Count; ++i) { out_polys.Add(new Path()); if (StripDupsAndGetBotPt(polys[i], out_polys[i], endtype == EndType.etClosed, out pt)) if (botIdx < 0 || pt.Y > botPt.Y || (pt.Y == botPt.Y && pt.X < botPt.X)) { botPt = pt; botIdx = i; } } if (endtype == EndType.etClosed && botIdx >= 0 && !Orientation(out_polys[botIdx])) ReversePaths(out_polys); Paths result; new PolyOffsetBuilder(out_polys, out result, delta, jointype, endtype, MiterLimit); return result; }
//------------------------------------------------------------------------------ public PolyOffsetBuilder(Paths pts, out Paths solution, double delta, JoinType jointype, EndType endtype, double limit = 0) { //precondition: solution != pts solution = new Paths(); if (ClipperBase.near_zero(delta)) {solution = pts; return; } m_p = pts; if (endtype != EndType.etClosed && delta < 0) delta = -delta; m_delta = delta; if (jointype == JoinType.jtMiter) { //m_miterVal: see offset_triginometry.svg in the documentation folder ... if (limit > 2) m_miterLim = 2 / (limit * limit); else m_miterLim = 0.5; if (endtype == EndType.etRound) limit = 0.25; } if (jointype == JoinType.jtRound || endtype == EndType.etRound) { if (limit <= 0) limit = 0.25; else if (limit > Math.Abs(delta)*0.25) limit = Math.Abs(delta)*0.25; //m_roundVal: see offset_triginometry2.svg in the documentation folder ... m_Steps360 = Math.PI / Math.Acos(1 - limit / Math.Abs(delta)); m_sin = Math.Sin(2 * Math.PI / m_Steps360); m_cos = Math.Cos(2 * Math.PI / m_Steps360); m_Steps360 /= Math.PI * 2; if (delta < 0) m_sin = -m_sin; } double deltaSq = delta * delta; solution.Capacity = pts.Count; for (m_i = 0; m_i < pts.Count; m_i++) { int len = pts[m_i].Count; if (len == 0 || (len < 3 && delta <= 0)) continue; if (len == 1) { if (jointype == JoinType.jtRound) { double X = 1.0, Y = 0.0; for (cInt j = 1; j <= Round(m_Steps360 * 2 * Math.PI); j++) { AddPoint(new IntPoint( Round(m_p[m_i][0].X + X * delta), Round(m_p[m_i][0].Y + Y * delta))); double X2 = X; X = X * m_cos - m_sin * Y; Y = X2 * m_sin + Y * m_cos; } } else { double X = -1.0, Y = -1.0; for (int j = 0; j < 4; ++j) { AddPoint(new IntPoint(Round(m_p[m_i][0].X + X * delta), Round(m_p[m_i][0].Y + Y * delta))); if (X < 0) X = 1; else if (Y < 0) Y = 1; else X = -1; } } continue; } //build normals ... normals.Clear(); normals.Capacity = len; for (int j = 0; j < len -1; ++j) normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j+1])); if (endtype == EndType.etClosed) normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0])); else normals.Add(new DoublePoint(normals[len - 2])); currentPoly = new Path(); if (endtype == EndType.etClosed) { m_k = len - 1; for (m_j = 0; m_j < len; ++m_j) OffsetPoint(jointype); solution.Add(currentPoly); } else { m_k = 0; for (m_j = 1; m_j < len - 1; ++m_j) OffsetPoint(jointype); IntPoint pt1; if (endtype == EndType.etButt) { m_j = len - 1; pt1 = new IntPoint((cInt)Round(pts[m_i][m_j].X + normals[m_j].X * delta), (cInt)Round(pts[m_i][m_j].Y + normals[m_j].Y * delta)); AddPoint(pt1); pt1 = new IntPoint((cInt)Round(pts[m_i][m_j].X - normals[m_j].X * delta), (cInt)Round(pts[m_i][m_j].Y - normals[m_j].Y * delta)); AddPoint(pt1); } else { m_j = len - 1; m_k = len - 2; m_sinA = 0; normals[m_j] = new DoublePoint(-normals[m_j].X, -normals[m_j].Y); if (endtype == EndType.etSquare) DoSquare(); else DoRound(); } //re-build Normals ... for (int j = len - 1; j > 0; j--) normals[j] = new DoublePoint(-normals[j - 1].X, -normals[j - 1].Y); normals[0] = new DoublePoint(-normals[1].X, -normals[1].Y); m_k = len - 1; for (m_j = m_k - 1; m_j > 0; --m_j) OffsetPoint(jointype); if (endtype == EndType.etButt) { pt1 = new IntPoint((cInt)Round(pts[m_i][0].X - normals[0].X * delta), (cInt)Round(pts[m_i][0].Y - normals[0].Y * delta)); AddPoint(pt1); pt1 = new IntPoint((cInt)Round(pts[m_i][0].X + normals[0].X * delta), (cInt)Round(pts[m_i][0].Y + normals[0].Y * delta)); AddPoint(pt1); } else { m_k = 1; m_sinA = 0; if (endtype == EndType.etSquare) DoSquare(); else DoRound(); } solution.Add(currentPoly); } } //finally, clean up untidy corners ... Clipper clpr = new Clipper(); clpr.AddPaths(solution, PolyType.ptSubject, true); if (delta > 0) { clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive); } else { IntRect r = clpr.GetBounds(); Path outer = new Path(4); outer.Add(new IntPoint(r.left - 10, r.bottom + 10)); outer.Add(new IntPoint(r.right + 10, r.bottom + 10)); outer.Add(new IntPoint(r.right + 10, r.top - 10)); outer.Add(new IntPoint(r.left - 10, r.top - 10)); clpr.AddPath(outer, PolyType.ptSubject, true); clpr.ReverseSolution = true; clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative); if (solution.Count > 0) solution.RemoveAt(0); } }