/// <summary> /// Присоединяет отверстие к полигону /// </summary> /// <param name="hi"></param> /// <param name="ptInHole"></param> /// <param name="ptInPolygon"></param> private void AppendHoleToPolygon(HoleInfo hi, int ptInHole, int ptInPolygon) { List <Point3d> newPlygon = new List <Point3d>(); for (int i = 0; i <= ptInPolygon; i++)//Добавить все точки полигона до точки присоединения { newPlygon.Add(Polygon[i]); } int currHoleIndex = ptInHole; do { newPlygon.Add(hi.Hole[currHoleIndex]); currHoleIndex = (currHoleIndex + 1) % hi.Hole.Count; }while (currHoleIndex != ptInHole); //Добавлять точки до полного обхода отверстия newPlygon.Add(hi.Hole[ptInHole]); //Еще раз добавить эту же точку отверстия for (int i = ptInPolygon; i < Polygon.Count; i++) //Добавить оставшиеся точки полигона { newPlygon.Add(Polygon[i]); } Polygon = newPlygon; }
private int GetVisiblePt(HoleInfo hi) { //Обозначения точек согласно https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf Point2d M = hi.MaxXPt; Point2d I = Point2d.Origin; int[] edge = GetEdgeOnHorizontalRay(M, out I); if (edge == null) { throw new Exception("Ошибка при определении видимой точки. Не найдено ребро, пересекающееся с горизонтальным лучем"); } int vertexOnEdgeIndex = Polygon[edge[0]].X > Polygon[edge[1]].X ? edge[0] : edge[1]; Point2d P = GetPt2DAt(vertexOnEdgeIndex); if (P.IsEqualTo(I)) { //Если точки совпали return(vertexOnEdgeIndex); } List <int> reflexPtsIndices = GetReflexVertsInTriangle(M, I, P); if (reflexPtsIndices.Count > 0) { return(GetVisiblePtFromReflexPts(M, reflexPtsIndices)); } else { return(vertexOnEdgeIndex); } }
// --------------------------------------------------------------- NewHole void NewHole() { HOLE_NUM++; STROKE_NUM = 0; HoleInfo info = CourseInfo[HOLE_NUM]; int yards = info.Yards; // from tee to cup int par = info.Par; var cup = new CircleGameObj(0, 0, 0, GameObjType.CUP); var green = new CircleGameObj(0, 0, 10, GameObjType.GREEN); var fairway = new RectGameObj(0 - (FairwayWidth / 2), 0 - (green.Radius + FairwayExtension), FairwayWidth, yards + (green.Radius + FairwayExtension) + 1, GameObjType.FAIRWAY); var rough = new RectGameObj(fairway.X - RoughAmt, fairway.Y - RoughAmt, fairway.Width + (2 * RoughAmt), fairway.Length + (2 * RoughAmt), GameObjType.ROUGH); BALL = new Ball(0, yards, 0, GameObjType.BALL); ScoreCardStartNewHole(); holeGeometry = new HoleGeometry(cup, green, fairway, rough, info.Hazard); w(" |> " + HOLE_NUM); w(" | "); w(" | "); w(" ^^^^^^^^^^^^^^^"); Console.WriteLine("Hole #{0}. You are at the tee. Distance {1} yards, par {2}.", HOLE_NUM, info.Yards, info.Par); w(info.Description); TeeUp(); }
protected override void OnNavigatedTo(NavigationEventArgs e) { STRBDpopin.Begin(); Constants.BoxPage.HamburgerVisible = false; if (e.Parameter != null && e.Parameter is HoleInfo) { CurHoleInfo = e.Parameter as HoleInfo; content_panel.DataContext = CurHoleInfo; } if (!(CurHoleInfo.type == HoleInfo.TYPE_IMAGE)) { IMGcontent.Visibility = Visibility.Collapsed; } if (!(CurHoleInfo.type == HoleInfo.TYPE_AUDIO)) { MEvoice.Visibility = Visibility.Collapsed; } else { MEvoice.AudioSource = new Uri(CurHoleInfo.url, UriKind.Absolute); } GetComments(); }
protected void add_hole(HoleInfo hi) { hi.nHole = Holes.Count; Holes.Add(hi); }
/// <summary> /// Cut a "partial" hole, ie we cut the mesh with the polygon once, and then /// extrude downwards to a planar version of the cut boundary. /// /// Currently only supports extruding downwards from topmost intersection. /// /// </summary> protected bool CutPartialHole(DMesh3 mesh, HoleInfo hi, Vector3d translate, bool bUpwards) { if (hi.IsVertical == false) { throw new Exception("unsupported!"); } Vector3d basePoint = CombinedBounds.Center - CombinedBounds.Extents.y * Vector3d.AxisY + translate; // do we need to compute spatial DS for each hole? not super efficient... DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, true); Vector3d direction = (bUpwards) ? Vector3d.AxisY : -Vector3d.AxisY; Vector3d center = basePoint + new Vector3d(hi.XZOffset.x, 0, hi.XZOffset.y) - 10000 * direction; Ray3d ray = new Ray3d(center, direction); int hit_tid = spatial.FindNearestHitTriangle(ray); if (hit_tid == DMesh3.InvalidID) { return(false); } IntrRay3Triangle3 intersection = MeshQueries.TriangleIntersection(mesh, hit_tid, ray); Vector3d inter_pos = ray.PointAt(intersection.RayParameter); Frame3f projectFrame = new Frame3f(ray.Origin, ray.Direction); int nVerts = 32; if (hi.Vertices != 0) { nVerts = hi.Vertices; } double angleShiftRad = hi.AxisAngleD * MathUtil.Deg2Rad; Polygon2d circle = Polygon2d.MakeCircle(hi.Radius, nVerts, angleShiftRad); try { EdgeLoop loop = null; MeshInsertProjectedPolygon insert = new MeshInsertProjectedPolygon(mesh, circle, projectFrame, hit_tid) { SimplifyInsertion = false }; if (insert.Insert()) { loop = insert.InsertedLoop; // [RMS] do we need to simplify for this one? //if (loop.VertexCount > circle.VertexCount) // loop = simplify_loop(mesh, loop, circle.VertexCount); MeshEditor editor = new MeshEditor(mesh); Vector3d base_pos = inter_pos; base_pos.y = basePoint.y + hi.PartialHoleBaseHeight; int N = loop.VertexCount; int[] newLoop = new int[N]; for (int k = 0; k < N; ++k) { newLoop[k] = mesh.AppendVertex(mesh, loop.Vertices[k]); Vector3d cur_v = mesh.GetVertex(newLoop[k]); cur_v.y = base_pos.y; mesh.SetVertex(newLoop[k], cur_v); } int base_vid = mesh.AppendVertex(base_pos); int[] fan_tris = editor.AddTriangleFan_OrderedVertexLoop(base_vid, newLoop); FaceGroupUtil.SetGroupID(mesh, fan_tris, hi.PartialHoleGroupID); int[] stitch_tris = editor.StitchLoop(loop.Vertices, newLoop); // need to remesh fan region because otherwise we get pathological cases RegionRemesher remesh = new RegionRemesher(mesh, fan_tris); remesh.SetTargetEdgeLength(2.0); remesh.SmoothSpeedT = 1.0; remesh.PreventNormalFlips = true; for (int k = 0; k < 25; ++k) { remesh.BasicRemeshPass(); } //remesh.EnableCollapses = remesh.EnableFlips = remesh.EnableSplits = false; //for (int k = 0; k < 20; ++k) // remesh.BasicRemeshPass(); remesh.BackPropropagate(); return(true); } else { return(false); } } catch (Exception e) { f3.DebugUtil.Log("partial hole {0} failed!! {1}", hi.nHole, e.Message); return(false); } }
/// <summary> /// Cut through-hole either vertically or horizontally. /// /// One current failure mode is if we get more than two ray-hits, which /// can happen due pathological cases or unexpected mesh shape. Currently /// trying to handle the pathological cases (ie ray hits adjacent triangles cases) /// via sorting, not sure if this works spectacularly well. /// /// </summary> protected bool CutThroughHole(DMesh3 mesh, HoleInfo hi, Vector3d translate) { Vector3d basePoint = CombinedBounds.Center - CombinedBounds.Extents.y * Vector3d.AxisY + translate; // do we need to compute spatial DS for each hole? not super efficient... DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, true); Vector3d origin = Vector3d.Zero; Vector3d direction = Vector3d.One; if (hi.IsVertical) { direction = Vector3d.AxisY; origin = basePoint + new Vector3d(hi.XZOffset.x, 0, hi.XZOffset.y) - 100 * direction; } else { origin = basePoint + hi.Height * Vector3d.AxisY; direction = Quaterniond.AxisAngleD(Vector3d.AxisY, hi.AroundAngle) * Vector3d.AxisX; } // Find upper and lower triangles that contain center-points of // holes we want to cut. This is the most error-prone part // because we depend on ray-hits, which is not very reliable... Ray3d ray1 = new Ray3d(origin, direction); Ray3d ray2 = new Ray3d(origin + 10000 * direction, -direction); if (hi.GroupIDFilters.a > 0) { spatial.TriangleFilterF = (tid) => { return(mesh.GetTriangleGroup(tid) == hi.GroupIDFilters.a); }; } int hit_1 = spatial.FindNearestHitTriangle(ray1); spatial.TriangleFilterF = null; if (hi.GroupIDFilters.b > 0) { spatial.TriangleFilterF = (tid) => { return(mesh.GetTriangleGroup(tid) == hi.GroupIDFilters.b); }; } int hit_2 = spatial.FindNearestHitTriangle(ray2); spatial.TriangleFilterF = null; if (hit_1 == DMesh3.InvalidID || hit_2 == DMesh3.InvalidID) { return(false); } if (hit_1 == hit_2) { return(false); } List <int> hitTris = new List <int>() { hit_1, hit_2 }; Frame3f projectFrame = new Frame3f(ray1.Origin, ray1.Direction); int nVerts = 32; if (hi.Vertices != 0) { nVerts = hi.Vertices; } double angleShiftRad = hi.AxisAngleD * MathUtil.Deg2Rad; Polygon2d circle = Polygon2d.MakeCircle(hi.Radius, nVerts, angleShiftRad); List <EdgeLoop> edgeLoops = new List <EdgeLoop>(); foreach (int hit_tid in hitTris) { try { MeshInsertProjectedPolygon insert = new MeshInsertProjectedPolygon(mesh, circle, projectFrame, hit_tid) { SimplifyInsertion = true }; if (insert.Insert()) { // if we have extra edges just randomly collapse EdgeLoop loop = insert.InsertedLoop; if (loop.VertexCount > circle.VertexCount) { loop = simplify_loop(mesh, loop, circle.VertexCount); } edgeLoops.Add(loop); } else { f3.DebugUtil.Log("insert.Insert() failed!!"); return(false); } } catch (Exception e) { // ignore this loop but we might already be in trouble... f3.DebugUtil.Log("insert.Insert() threw exception for hole {0}!!", hi.nHole); f3.DebugUtil.Log(e.Message); } } if (edgeLoops.Count != 2) { return(false); } try { MeshEditor editor = new MeshEditor(mesh); EdgeLoop l0 = edgeLoops[0]; EdgeLoop l1 = edgeLoops[1]; l1.Reverse(); editor.StitchVertexLoops_NearestV(l0.Vertices, l1.Vertices); // split edges around the holes we cut. This is helpful // if we are going to do additional operations in these areas, // as it gives us extra rings to work with //MeshEdgeSelection edges = new MeshEdgeSelection(mesh); //edges.SelectVertexEdges(l0.Vertices); //edges.SelectVertexEdges(l1.Vertices); //DMesh3.EdgeSplitInfo splitInfo; //foreach ( int eid in edges ) // mesh.SplitEdge(eid, out splitInfo); return(true); } catch { f3.DebugUtil.Log("stitch threw exception!"); return(false); } }
void Update() { // Return if game is not active if (gameRef == null || !gameRef.enabled) { return; } State state = gameRef.GetState(); if (!renderPowerbar) { powerbarParent.SetActive(false); distanceDisplay.SetActive(true); distanceText.text = MathUtil.ToYards(gameRef.GetCurrentDistance().GetCurrentDistance()).ToString("F2") + "y"; } else { powerbarParent.SetActive(true); distanceDisplay.SetActive(false); } // ShotMode Mode m = gameRef.GetShotMode().GetShotMode(); switch (m) { case Mode.NORMAL: barColor = Color.yellow; powerBarIcon.texture = normalSprite; powerShotsRemaining.color = Color.gray; powerShotsRemaining.text = gameRef.GetShotMode().GetPowerShots().ToString(); break; case Mode.POWER: barColor = Color.red; powerBarIcon.texture = powerSprite; powerShotsRemaining.color = Color.white; powerShotsRemaining.text = gameRef.GetShotMode().GetPowerShots().ToString(); break; case Mode.APPROACH: barColor = Color.green; powerBarIcon.texture = approachSprite; powerShotsRemaining.text = "A"; break; default: throw new Exception(String.Format("Unsupported shot mode {0}", m)); } fillBar.color = barColor; negBar.color = barColor; barBackground.color = Color.Lerp(barColor, Color.black, .5f); // Powerbar update. Do this every frame. Rest can be done whenever current = (float)gameRef.GetPowerbar().GetCurrent(); power = (float)gameRef.GetPowerbar().GetPower(); accuracy = (float)gameRef.GetPowerbar().GetAccuracy(); fillBar.fillAmount = current; negBar.fillAmount = (current >= -Powerbar.NEGATIVE_PART) ? -current : Powerbar.NEGATIVE_PART; powerMarker.value = (power == 0) ? current : power; if (current >= 0) { accMarker.gameObject.SetActive(true); accMarkerNeg.gameObject.SetActive(false); } else { accMarker.gameObject.SetActive(false); accMarkerNeg.gameObject.SetActive(true); } accMarker.value = (accuracy == 0) ? current : accMarker.value; accMarkerNeg.value = (accuracy == 0) ? -current : accMarkerNeg.value; int maxVal = (int)MathUtil.ToYardsRounded(gameRef.GetBag().GetClub().GetDistance()); underText[0].text = (int)((float)maxVal) + "y"; underText[1].text = (int)((float)maxVal * .75f) + "y"; underText[2].text = (int)((float)maxVal * .5f) + "y"; underText[3].text = (int)((float)maxVal * .25f) + "y"; // Bag update clubText.text = gameRef.GetBag().GetClub().GetName(); remYdText.text = "Pin: " + (int)gameRef.GetBall().DistanceToHole() + "y"; clubMaxText.text = maxVal + "y"; // Hole info update HoleInfo holeInfo = gameRef.GetHoleInfo(); HoleData holeData = gameRef.GetHoleBag().GetCurrentHoleData(); holeText.text = gameRef.GetHoleBag().GetCurrentHoleNumber().ToString(); parText.text = "Par " + holeInfo.GetPar().ToString(); yardText.text = MathUtil.ToYardsRounded(holeInfo.GetLength()).ToString() + "y"; strokeText.text = holeData != null?holeData.GetStrokes().ToString() : ""; // Wind info update Wind tWind = gameRef.GetWind(); Vector3 camAngles = gameRef.GetCameraObject().transform.rotation.eulerAngles; // Orient arrow correctly camAngles[1] = -camAngles[1] - MathUtil.RadsToDeg((float)tWind.GetAngle()) + 90; //Random jittering according to speed. second value is a multiplier camAngles[1] += UnityEngine.Random.Range(-tWind.GetSpeed(), tWind.GetSpeed()) * 5; camAngles[0] = 0; arrowParent.transform.eulerAngles = camAngles; windText.text = String.Format("{0}m", tWind.GetVisualSpeed().ToString("F0")); // Lie image update if (state is PrepareState) { switch (gameRef.GetBall().GetMaterialType()) { case MaterialType.GREEN: lieImage.texture = lieImageGreen; break; case MaterialType.FAIRWAY: lieImage.texture = lieImageFairway; break; case MaterialType.ROUGH: lieImage.texture = lieImageRough; break; case MaterialType.BUNKER: lieImage.texture = lieImageBunker; break; case MaterialType.WATER: lieImage.texture = lieImageWater; break; case MaterialType.NONE: lieImage.texture = lieImageNone; break; default: throw new Exception(String.Format("Unsupported MaterialType: {0}", gameRef.GetBall().GetMaterialType())); } } // Lie percentage update if (state is RunningState) { float lie = gameRef.GetBall().GetLie(); lieText.text = String.Format("{0}%", (lie * 100).ToString("F0")); } else { Tuple <float, float> lieBounds = gameRef.GetBall().GetTerrainType().GetBounds(); lieText.text = (lieBounds.Item1 == lieBounds.Item2) ? String.Format("{0}%", (lieBounds.Item1 * 100).ToString("F0")) : String.Format("{0}%-{1}%", (lieBounds.Item1 * 100).ToString("F0"), (lieBounds.Item2 * 100).ToString("F0")); } // Lie angle update if (state is PrepareState || state is IdleState) { Tuple <float, float> terrainAngle = gameRef.GetBall().GetTerrainAngle(); aAngle.text = terrainAngle.Item1.ToString("F0") + "°"; aAngle.color = Mathf.Abs(terrainAngle.Item1) < 0.5f ? WHITE : terrainAngle.Item1 < 0f ? BLUE : RED; bAngle.text = terrainAngle.Item2.ToString("F0") + "°"; bAngle.color = Mathf.Abs(terrainAngle.Item2) < 0.5f ? WHITE : terrainAngle.Item2 < 0f ? BLUE : RED; } // BonusText update List <Item> heldItems = gameRef.GetPlayerAttributes().GetHeldItems(); if (heldItems.Count <= 20) { bonusText.text = ""; foreach (Item i in heldItems) { bonusText.text += i.GetName() + "\n"; } } else { bonusText.text = "...\n"; foreach (Item i in heldItems.Skip(Math.Max(0, heldItems.Count() - 19))) { bonusText.text += i.GetName() + "\n"; } } // Player attributes update PlayerAttributes plr = gameRef.GetPlayerAttributes(); playerinfoText[0].text = (plr.GetPower() * 100).ToString("F0"); playerinfoText[1].text = (plr.GetControl() * 100).ToString("F0"); playerinfoText[2].text = (plr.GetImpact() * 100).ToString("F0"); playerinfoText[3].text = (plr.GetSpin() * 100).ToString("F0"); // ToggleText update camToggleText.text = Char.ToUpper(gameRef.GetTarget().ToString()[0]) + gameRef.GetTarget().ToString().ToLower().Substring(1); Target target = gameRef.GetTarget(); if (target == Target.BALL || target == Target.FREE) { camToggleText.text = "View Cursor"; } else { camToggleText.text = "Reset Camera"; } normalToggleText.text = gc.greenNormalMap ? "Reset Green" : "View Green Normals"; // Post hole text holeWinText.text = MathUtil.GolfTerms(holeData.GetStrokes(), holeInfo.GetPar()); // Shot Bonus update if (shotBonusActive) { if (Time.time >= shotBonusTarget) { shotBonusActive = false; shotBonusDisplay.transform.position = shotBonusDefaultPosition; shotBonusDisplay.SetActive(false); } else { shotBonusDisplay.transform.position += (Vector3.up) * Time.deltaTime * 5; } } }
public void SetHoleInfo(HoleInfo holeInfo) { this.holeInfo = holeInfo; }
public void SingleMove(HoleInfo moveInfo, string axisType) { if (moveInfo.X.HasValue) { decimal actPosX = Contra.GetActPosX(axisType); isXPlus = moveInfo.X.Value >= actPosX; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisX, GetMovePosition("X", moveInfo.X, actPosX, Contra.LogPosX, isXPlus != isOldXPlus, isOldXPlus, out jianxiX), Contra.StartSpeed, (int)AxisSet.SpeedXPerSecond, (double)Contra.AddSpeedTime); isOldXPlus = isXPlus; } if (moveInfo.Y.HasValue) { decimal actPosY = Contra.GetActPosY(axisType); isYPlus = moveInfo.Y.Value >= actPosY; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisY, GetMovePosition("Y", moveInfo.Y, actPosY, Contra.LogPosY, isYPlus != isOldYPlus, isOldYPlus, out jianxiY), Contra.StartSpeed, (int)AxisSet.SpeedYPerSecond, (double)Contra.AddSpeedTime); isOldYPlus = isYPlus; } if (moveInfo.W.HasValue) { decimal actPosW = Contra.GetActPosW(axisType); isWPlus = moveInfo.W.Value >= actPosW; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisW, GetMovePosition("W", moveInfo.W, actPosW, Contra.LogPosW, isWPlus != isOldWPlus, isOldWPlus, out jianxiW), Contra.StartSpeed, (int)AxisSet.SpeedWPerSecond, (double)Contra.AddSpeedTime); isOldWPlus = isWPlus; } if (moveInfo.Z.HasValue) { Contra.LogPosZ = GetActPos(AxisSet.ZReadAxis) * AxisSet.ZResolution; Contra.LogPosA = GetLogPos(AxisSet.AxisZ); Contra.TempLogPosA = Contra.LogPosZ + Contra.TempLogPosZ - Contra.LogPosA; Contra.TempLogPosA55 = Contra.LogPosZ + Contra.TempLogPosZ55 - Contra.LogPosA; Contra.TempLogPosA56 = Contra.LogPosZ + Contra.TempLogPosZ56 - Contra.LogPosA; Contra.TempLogPosA57 = Contra.LogPosZ + Contra.TempLogPosZ57 - Contra.LogPosA; Contra.TempLogPosA58 = Contra.LogPosZ + Contra.TempLogPosZ58 - Contra.LogPosA; Contra.TempLogPosA59 = Contra.LogPosZ + Contra.TempLogPosZ59 - Contra.LogPosA; decimal actPosA = Contra.GetActPosZ(axisType); isAPlus = moveInfo.Z.Value >= actPosA; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisZ, GetMovePosition("Z", moveInfo.Z, actPosA, Contra.LogPosA, isAPlus != isOldAPlus, isOldAPlus, out jianxiA), Contra.StartSpeed, (int)AxisSet.SpeedZPerSecond, (double)Contra.AddSpeedTime); isOldAPlus = isAPlus; } if (moveInfo.B.HasValue) { decimal actPosB = Contra.GetActPosB(axisType); isBPlus = moveInfo.B.Value >= actPosB; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisB, GetMovePosition("B", moveInfo.B, actPosB, Contra.LogPosB, isBPlus != isOldBPlus, isOldBPlus, out jianxiB), Contra.StartSpeed, (int)AxisSet.SpeedBPerSecond, (double)Contra.AddSpeedTime); isOldBPlus = isBPlus; } if (moveInfo.C.HasValue) { decimal actPosC = Contra.GetActPosC(axisType); isCPlus = moveInfo.C.Value >= actPosC; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisC, GetMovePosition("C", moveInfo.C, actPosC, Contra.LogPosC, isCPlus != isOldCPlus, isOldCPlus, out jianxiC), Contra.StartSpeed, (int)AxisSet.SpeedCPerSecond, (double)Contra.AddSpeedTime); isOldCPlus = isCPlus; } isMove = true; }
private bool isMove = false;//TODO public void SingleMove(HoleInfo moveInfo, string axisType) { if (moveInfo.X.HasValue) { decimal actPosX = Contra.GetActPosX(axisType); isXPlus = moveInfo.X.Value >= actPosX; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisX, GetMovePosition("X", moveInfo.X, actPosX, Contra.LogPosX, isXPlus != isOldXPlus, isOldXPlus, out jianxiX), Contra.StartSpeed, (int)AxisSet.SpeedXPerSecond, (double)Contra.AddSpeedTime); isOldXPlus = isXPlus; } if (moveInfo.Y.HasValue) { decimal actPosY = Contra.GetActPosY(axisType); isYPlus = moveInfo.Y.Value >= actPosY; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisY, GetMovePosition("Y", moveInfo.Y, actPosY, Contra.LogPosY, isYPlus != isOldYPlus, isOldYPlus, out jianxiY), Contra.StartSpeed, (int)AxisSet.SpeedYPerSecond, (double)Contra.AddSpeedTime); isOldYPlus = isYPlus; } if (moveInfo.W.HasValue) { decimal actPosW = Contra.GetActPosW(axisType); isWPlus = moveInfo.W.Value >= actPosW; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisW, GetMovePosition("W", moveInfo.W, actPosW, Contra.LogPosW, isWPlus != isOldWPlus, isOldWPlus, out jianxiW), Contra.StartSpeed, (int)AxisSet.SpeedWPerSecond, (double)Contra.AddSpeedTime); isOldWPlus = isWPlus; } if (moveInfo.Z.HasValue) { Contra.LogPosZ = GetActPos(AxisSet.ZReadAxis) * AxisSet.ZResolution; Contra.LogPosA = GetLogPos(AxisSet.AxisZ); Contra.TempLogPosA = Contra.LogPosZ + Contra.TempLogPosZ - Contra.LogPosA; Contra.TempLogPosA55 = Contra.LogPosZ + Contra.TempLogPosZ55 - Contra.LogPosA; Contra.TempLogPosA56 = Contra.LogPosZ + Contra.TempLogPosZ56 - Contra.LogPosA; Contra.TempLogPosA57 = Contra.LogPosZ + Contra.TempLogPosZ57 - Contra.LogPosA; Contra.TempLogPosA58 = Contra.LogPosZ + Contra.TempLogPosZ58 - Contra.LogPosA; Contra.TempLogPosA59 = Contra.LogPosZ + Contra.TempLogPosZ59 - Contra.LogPosA; decimal actPosA = Contra.GetActPosZ(axisType); isAPlus = moveInfo.Z.Value >= actPosA; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisZ, GetMovePosition("Z", moveInfo.Z, actPosA, Contra.LogPosA, isAPlus != isOldAPlus, isOldAPlus, out jianxiA), Contra.StartSpeed, (int)AxisSet.SpeedZPerSecond, (double)Contra.AddSpeedTime); isOldAPlus = isAPlus; } if (moveInfo.B.HasValue) { decimal actPosB = Contra.GetActPosB(axisType); isBPlus = moveInfo.B.Value >= actPosB; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisB, GetMovePosition("B", moveInfo.B, actPosB, Contra.LogPosB, isBPlus != isOldBPlus, isOldBPlus, out jianxiB), Contra.StartSpeed, (int)AxisSet.SpeedBPerSecond, (double)Contra.AddSpeedTime); isOldBPlus = isBPlus; } if (moveInfo.C.HasValue) { decimal actPosC = Contra.GetActPosC(axisType); isCPlus = moveInfo.C.Value >= actPosC; CtrlCard.Sym_AbsoluteMove(AxisSet.AxisC, GetMovePosition("C", moveInfo.C, actPosC, Contra.LogPosC, isCPlus != isOldCPlus, isOldCPlus, out jianxiC), Contra.StartSpeed, (int)AxisSet.SpeedCPerSecond, (double)Contra.AddSpeedTime); isOldCPlus = isCPlus; } isMove = true; }