public Vector Turn(ClockDirections direction, int degrees) { if (degrees <= 0) { throw new ArgumentOutOfRangeException(nameof(degrees)); } degrees %= 360; var heading = this.Heading; switch (direction) { case ClockDirections.Clockwise: heading += degrees; if (heading >= 360) { heading -= 360; } break; case ClockDirections.CounterClockwise: heading -= degrees; if (heading < 360) { heading += 360; } break; } return(new Vector(heading, this.X, this.Y)); }
/// <summary> /// /// </summary> /// <param name="sides">3 to 15.</param> /// <param name="length">length of each side. 20 to 500 in cm.</param> /// <param name="speed">cm/s 10 to 100.</param> /// /// <param name="clockDirection">Clock direction.</param> public void FlyPolygon(int sides, int length, int speed, ClockDirections clockDirection) { if (!this.CanManeuver) { return; } if (sides < 3 || sides > 15) { throw new ArgumentOutOfRangeException($"{nameof(sides)} allowed values: 3 to 15"); } this.SetSpeed(speed); var turnMethod = default(Action <int>); switch (clockDirection) { case ClockDirections.Clockwise: turnMethod = this.TurnClockwise; break; case ClockDirections.CounterClockwise: turnMethod = this.TurnCounterClockwise; break; } var angle = (int)Math.Round(360.0 / sides); for (var i = 0; i < sides; ++i) { this.GoForward(length); turnMethod(angle); } }
private static ClockDirections GetGeneralDir(Vector bondVector) { double bondAngle = Vector.AngleBetween(BasicGeometry.ScreenNorth, bondVector); ClockDirections hour = (ClockDirections)BasicGeometry.SnapToClock(bondAngle); return(hour); }
private static ClockDirections GetNewSproutDirection(ClockDirections hour) { ClockDirections newTag; switch (hour) { case ClockDirections.I: newTag = ClockDirections.III; break; case ClockDirections.II: newTag = ClockDirections.IV; break; case ClockDirections.III: newTag = ClockDirections.II; break; case ClockDirections.IV: newTag = ClockDirections.II; break; case ClockDirections.V: newTag = ClockDirections.III; break; case ClockDirections.VI: newTag = ClockDirections.VIII; break; case ClockDirections.VII: newTag = ClockDirections.IX; break; case ClockDirections.VIII: newTag = ClockDirections.X; break; case ClockDirections.IX: newTag = ClockDirections.XI; break; case ClockDirections.X: newTag = ClockDirections.VIII; break; case ClockDirections.XII: newTag = ClockDirections.I; break; default: newTag = ClockDirections.II; break; } return(newTag); }
/// <summary> /// tells you where to put a new atom /// </summary> /// <param name="lastAtomVisual"></param> /// <param name="congestedPositions">Places to avoid dumping the new atom</param> /// <returns></returns> private (Point NewPos, ClockDirections sproutDir) GetNewChainEndPos(AtomVisual lastAtomVisual) { ClockDirections GetGeneralDir(Vector bondVector) { double bondAngle = Vector.AngleBetween(BasicGeometry.ScreenNorth, bondVector); ClockDirections hour = (ClockDirections)BasicGeometry.SnapToClock(bondAngle); return(hour); } var lastAtom = lastAtomVisual.ParentAtom; Vector newDirection; ClockDirections newTag; if (lastAtom.Degree == 0) //isolated atom { newDirection = ClockDirections.II.ToVector() * EditViewModel.Model.XamlBondLength; newTag = ClockDirections.II; } else if (lastAtom.Degree == 1) { Vector bondVector = lastAtom.Position - lastAtom.Neighbours.First().Position; var hour = GetGeneralDir(bondVector); if (VirginAtom(lastAtom)) //it hasn't yet sprouted { //Tag is used to store the direction the atom sprouted from its previous atom newTag = GetNewSproutDirection(hour); newDirection = newTag.ToVector() * EditViewModel.Model.XamlBondLength; } else //it has sprouted, so where to put the new branch? { var vecA = ((ClockDirections)lastAtom.Tag).ToVector(); vecA.Normalize(); var vecB = -bondVector; vecB.Normalize(); var balancingVector = -(vecA + vecB); balancingVector.Normalize(); newTag = GetGeneralDir(balancingVector); newDirection = balancingVector * EditViewModel.Model.XamlBondLength; } } else if (lastAtom.Degree == 2) { var balancingVector = lastAtom.BalancingVector(); balancingVector.Normalize(); newDirection = balancingVector * EditViewModel.Model.XamlBondLength; newTag = GetGeneralDir(balancingVector); } else //lastAtom.Degree >= 2: could get congested { FindOpenSpace(lastAtom, EditViewModel.Model.XamlBondLength, out newDirection); newTag = GetGeneralDir(newDirection); } return(newDirection + lastAtom.Position, newTag); }