public ClothoidArc2(double l0, Vec2d point0, Vec2d point1, double radius0, double radius1, double a) { // Correccion sobre los radios. if (SysMath.Sign(radius1) != SysMath.Sign(radius0)) { if (double.IsInfinity(radius0)) { radius0 = SysMath.Sign(radius1) * double.PositiveInfinity; } else if (double.IsInfinity(radius1)) { radius1 = SysMath.Sign(radius0) * double.PositiveInfinity; } else { // Se deja tal cual. //// Se toma el radio inicio como infinito. ////radius0 = SysMath.Sign(radius1) * double.PositiveInfinity; } } if (SysMath.Abs(radius0) > SysMath.Abs(radius1)) { // t positivas this.invertY = radius1 < 0; } else { // t negativa this.invertY = radius1 > 0; } // Diferencia de puntos en coordenadas reales. Vec2d v01 = point1.Sub(point0); this.a = a; // Desarrollo segun el radio en el punto (0) y (1). double l0_n = ClothoUtils.ClothoL(radius0, this.invertY, this.a); double l1_n = ClothoUtils.ClothoL(radius1, this.invertY, this.a); // Coordenadas en el punto (0) y (1) para una clotoide normalizada. Vec2d p0_n = ClothoUtils.Clotho(l0_n, this.invertY, this.a); Vec2d p1_n = ClothoUtils.Clotho(l1_n, this.invertY, this.a); Vec2d v01_n = p1_n.Sub(p0_n); // Rotacion de v01_n -> v01. double r = vecMath.Angle(v01_n, v01); // Transformacion a aplicar. this.transform = Transform2.Translate(point1.X - p1_n.X, point1.Y - p1_n.Y) .Mult(Transform2.Rotate(p1_n.X, p1_n.Y, r)); this.l0 = l0_n; this.l1 = l1_n; this.SetTInterval(l0, l0 + (this.l1 - this.l0)); }
// -------------------------------------------------------------------------------------------------------------------------- /// <summary> /// Case insensitive string comparison. May not work for all cultures. Suitable for fast sorting of alphanumeric strings /// only. /// </summary> public static int AlphaNumericStrCompare_NoCase(string x, string y) { int xLen = x.Length; int yLen = y.Length; int minLen = SysMath.Min(xLen, yLen); int comp = 0; int i = 0; while (comp == 0 & i < minLen) { int xc = x[i]; int yc = y[i]; if ((uint)(xc - 'a') <= (uint)('z' - 'a')) { xc -= 0x20; } if ((uint)(yc - 'a') <= (uint)('z' - 'a')) { yc -= 0x20; } comp = xc - yc; ++i; } if (comp == 0) { comp = xLen - yLen; } return(SysMath.Sign(comp)); }
public static ClothoidArc2 BuildSimple(double radius0, double radius1, double a, ITransform2 transform) { // Correccion sobre los radios. if (SysMath.Sign(radius1) != SysMath.Sign(radius0)) { if (double.IsInfinity(radius0)) { radius0 = SysMath.Sign(radius1) * double.PositiveInfinity; } else if (double.IsInfinity(radius1)) { radius1 = SysMath.Sign(radius0) * double.PositiveInfinity; } else { // No se permite cambio de signo en el radio. Funcionaria??? Contract.Assert(false); } } // Desarrollo segun el radio en el punto (0) y (1). double l0 = ClothoUtils.ClothoL(radius0, false, a); double l1 = ClothoUtils.ClothoL(radius1, false, a); ClothoidArc2 clotho = new ClothoidArc2(transform, l0, l1, false, a); clotho.SetTInterval(0, Math.Abs(l1 - l0)); return(clotho); }
private void updateMouseInput() { var currentState = Mouse.GetState(); if (_previousMouseState.X != currentState.X || _previousMouseState.Y != currentState.Y) { if (isAnyMouseButtonPressed(currentState)) { _inputProcessor.touchDragged(currentState.X, currentState.Y, 0); } else { _inputProcessor.mouseMoved(currentState.X, currentState.Y); } } if (_previousMouseState.ScrollWheelValue != currentState.ScrollWheelValue) { _inputProcessor.scrolled( Math.Sign(currentState.ScrollWheelValue - _previousMouseState.ScrollWheelValue)); } if (_previousMouseState.LeftButton != currentState.LeftButton) { if (currentState.LeftButton == ButtonState.Pressed) { _inputProcessor.touchDown(currentState.X, currentState.Y, 0, org.mini2Dx.gdx.Input.Buttons.LEFT); } else { _inputProcessor.touchUp(currentState.X, currentState.Y, 0, org.mini2Dx.gdx.Input.Buttons.LEFT); } } if (_previousMouseState.MiddleButton != currentState.MiddleButton) { if (currentState.MiddleButton == ButtonState.Pressed) { _inputProcessor.touchDown(currentState.X, currentState.Y, 0, org.mini2Dx.gdx.Input.Buttons.MIDDLE); } else { _inputProcessor.touchUp(currentState.X, currentState.Y, 0, org.mini2Dx.gdx.Input.Buttons.MIDDLE); } } if (_previousMouseState.RightButton != currentState.RightButton) { if (currentState.RightButton == ButtonState.Pressed) { _inputProcessor.touchDown(currentState.X, currentState.Y, 0, org.mini2Dx.gdx.Input.Buttons.RIGHT); } else { _inputProcessor.touchUp(currentState.X, currentState.Y, 0, org.mini2Dx.gdx.Input.Buttons.RIGHT); } } _previousMouseState = currentState; }
public ClothoidArc2(double l0, Vector2d point0, Vector2d point1, double radius0, double radius1) { // Correccion sobre los radios. if (SysMath.Sign(radius1) != SysMath.Sign(radius0)) { if (double.IsInfinity(radius0)) { radius0 = SysMath.Sign(radius1) * double.PositiveInfinity; } else if (double.IsInfinity(radius1)) { radius1 = SysMath.Sign(radius0) * double.PositiveInfinity; } else { // No se permite cambio de signo en el radio. Funcionaria??? Contract.Assert(false); } } if (SysMath.Abs(radius0) > SysMath.Abs(radius1)) { // t positivas this.InvertY = radius1 < 0; } else { // t negativa this.InvertY = radius1 > 0; } // Diferencia de puntos en coordenadas reales. Vector2d v01 = point1.Sub(point0); this.A = SolveParam(v01.Length, radius0, radius1); // Desarrollo segun el radio en el punto (0) y (1). double l0_n = ClothoUtils.ClothoL(radius0, this.InvertY, this.A); double l1_n = ClothoUtils.ClothoL(radius1, this.InvertY, this.A); // Coordenadas en el punto (0) y (1) para una clotoide normalizada. Point2d p0_n = ClothoUtils.Clotho(l0_n, this.InvertY, this.A); Point2d p1_n = ClothoUtils.Clotho(l1_n, this.InvertY, this.A); Vector2d v01_n = p1_n.Sub(p0_n); // Rotacion de v01_n -> v01. double r = v01_n.AngleTo(v01); // Transformacion a aplicar. this.transform = Transform2.Translate(point1.X - p1_n.X, point1.Y - p1_n.Y) .Concat(Transform2.Rotate(p1_n.X, p1_n.Y, r)); this.l0 = l0_n; this.l1 = l1_n; this.SetTInterval(l0, l0 + (this.l1 - this.l0)); }
/// <summary> /// Computes the new motor velocity based on the current velocity, such that the velocity always moves towards /// the set point (if regulation is active), or the acceleration curve dictated by the <see cref="Acceleration" /> /// property. /// The magnitude of the returned speed will never be greater than <see cref="StepperMotor.MaximumSpeed" /> which in turn /// can never /// exceed <see cref="StepperMotor.MaximumPossibleSpeed" />. /// <see cref="StepperMotor.MaximumSpeed" />. /// </summary> /// <returns>The computed velocity, in steps per second.</returns> /// <remarks> /// A positive value indicates speed in the forward direction, while a negative value indicates speed in the reverse /// direction. /// 'forward' is defined as motion towards a higher position value; 'reverse' is defined as motion towards a lower /// position value. /// No attempt is made here to define the mechanical direction. A speed value that is within /// <see cref="StepperMotor.MotorStoppedThreshold" /> /// of zero is considered to mean that the motor should be stopped. /// </remarks> double ComputeAcceleratedVelocity() { var distanceToGo = ComputeDistanceToTarget(); var absoluteDistance = Math.Abs(distanceToGo); var direction = Math.Sign(distanceToGo); if (distanceToGo == 0) { return(0.0); // We're there. } if (!IsMoving) { return(Math.Sqrt(2.0 * Acceleration) * direction); // Accelerate away from stop. } // Compute the unconstrained target speed based on the deceleration curve or the regulation set point. var targetSpeed = regulating ? speedSetpoint : Math.Sqrt(2.0 * absoluteDistance * Acceleration) * direction; // The change in speed is a function of the absolute current speed and acceleration. var increment = Acceleration / Math.Abs(motorSpeed); var directionOfChange = Math.Sign(targetSpeed - motorSpeed); var newSpeed = motorSpeed + increment * directionOfChange; // The computed new speed must be constrained by both the MaximumSpeed and the acceleration curve. var clippedSpeed = newSpeed.ConstrainToLimits(-maximumSpeed, +maximumSpeed); return(clippedSpeed); }
public static WavefrontFormat DrawClothoRadius(this WavefrontFormat wf, bool invertY, double a, string radiusColor) { List <int> indices = new List <int>(); double lmax = ClothoUtils.GetMaxL(a); int c = 100; for (int i = -c; i <= c; i++) { double s = i * lmax / c; double r = ClothoUtils.ClothoRadius(s, invertY, a); if (double.IsInfinity(r)) { r = SysMath.Sign(r) * 1000; } int v0 = wf.AddVertex(new Point2d(s, r)); indices.Add(v0); //double dx, dy; //MathUtils.DClotho(s, r, a, out dx, out dy); } wf.UseMaterial(radiusColor); wf.AddLines(indices, false); return(wf); }
/// <summary> /// Moves the motor at a regulated speed, using acceleration whenever the speed changes. /// Once moving, the speed may be changed by calling this method again with the new value. /// To decelerate to a stop, call this method with a speed of 0. /// </summary> /// <param name="speed">The target speed.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// speed;speed must be in the range -MaximumPossibleSpeed to /// +MaximumPossibleSpeed /// </exception> public void MoveAtRegulatedSpeed(double speed) { var absoluteSpeed = Math.Abs(speed); if (absoluteSpeed > MaximumPossibleSpeed) { throw new ArgumentOutOfRangeException("speed", "speed must be in the range -MaximumPossibleSpeed to +MaximumPossibleSpeed"); } //if (maximumSpeed < absoluteSpeed) // maximumSpeed = absoluteSpeed; // Set the target position, effectively, infinitely far away so we will never stop. targetPosition = speed >= 0 ? int.MaxValue : int.MinValue; speedSetpoint = absoluteSpeed < MotorStoppedThreshold ? 0.0 : speed; var direction = (short)Math.Sign(targetPosition - currentPosition); lock (motorUpdateLock) { regulating = true; if (!IsMoving) { StartStepping(direction); } } }
/// <summary> /// Returns the root of the number. /// </summary> /// <param name="value">The value.</param> /// <param name="root">The root.</param> /// <returns>System.Double.</returns> public static double Root(double value, int root) { if (IsZeroSign(root)) { throw new DivideByZeroException("Root cannot be zero."); } return(IsOdd(root) ? NMath.Sign(value) * Pow(NMath.Abs(value), 1d / root) : Pow(value, 1d / root)); }
private void updateMouseInput() { if (previousMouseState.X != currentMouseState.X || previousMouseState.Y != currentMouseState.Y) { if (isAnyMouseButtonPressed(currentMouseState)) { inputProcessor.touchDragged(currentMouseState.X, currentMouseState.Y, 0); } else { inputProcessor.mouseMoved(currentMouseState.X, currentMouseState.Y); } } if (previousMouseState.ScrollWheelValue != currentMouseState.ScrollWheelValue) { inputProcessor.scrolled(0, -Math.Sign(currentMouseState.ScrollWheelValue - previousMouseState.ScrollWheelValue)); } if (previousMouseState.LeftButton != currentMouseState.LeftButton) { if (currentMouseState.LeftButton == ButtonState.Pressed) { inputProcessor.touchDown(currentMouseState.X, currentMouseState.Y, 0, Org.Mini2Dx.Gdx.Input_n_Buttons.LEFT_); } else { inputProcessor.touchUp(currentMouseState.X, currentMouseState.Y, 0, Org.Mini2Dx.Gdx.Input_n_Buttons.LEFT_); } } if (previousMouseState.MiddleButton != currentMouseState.MiddleButton) { if (currentMouseState.MiddleButton == ButtonState.Pressed) { inputProcessor.touchDown(currentMouseState.X, currentMouseState.Y, 0, Org.Mini2Dx.Gdx.Input_n_Buttons.MIDDLE_); } else { inputProcessor.touchUp(currentMouseState.X, currentMouseState.Y, 0, Org.Mini2Dx.Gdx.Input_n_Buttons.MIDDLE_); } } if (previousMouseState.RightButton != currentMouseState.RightButton) { if (currentMouseState.RightButton == ButtonState.Pressed) { inputProcessor.touchDown(currentMouseState.X, currentMouseState.Y, 0, Org.Mini2Dx.Gdx.Input_n_Buttons.RIGHT_); } else { inputProcessor.touchUp(currentMouseState.X, currentMouseState.Y, 0, Org.Mini2Dx.Gdx.Input_n_Buttons.RIGHT_); } } }
/// <summary> /// The x-coordinates of a line intersecting a circle centered at 0,0. /// </summary> /// <param name="radius">>Radius of the circle centered at 0,0.</param> /// <param name="lineLength"></param> /// <param name="incidence"></param> /// <param name="determinant"></param> /// <param name="delta"></param> /// <returns></returns> public static double[] CircleLineIntersectX( double radius, double lineLength, double incidence, double determinant, Offset delta) { return((determinant * delta.Y() / lineLength.Squared()).PlusMinus( NMath.Sign(delta.Y()) * delta.X() * NMath.Sqrt(incidence) / lineLength.Squared())); }
void HandleAccelerationTimerTick(object ignored) { var accelerationSign = Math.Sign(targetVelocity - CurrentVelocity); var acceleratedVelocity = ComputeAcceleratedVelocity(Acceleration * accelerationSign); var newVelocity = accelerationSign >= 0 ? Accelerate(acceleratedVelocity) : Decelerate(acceleratedVelocity); Debug.Print("Velocity " + newVelocity.ToString("F4")); motorWinding.SetOutputPowerAndPolarity(newVelocity); CurrentVelocity = newVelocity; }
private void HandleAccelerationTimerTick(object ignored) { int num = Math.Sign(_targetVelocity - CurrentVelocity); double acceleratedVelocity = ComputeAcceleratedVelocity(Acceleration * num); double duty = num >= 0 ? Accelerate(acceleratedVelocity) : Decelerate(acceleratedVelocity); Debug.Print("Velocity " + duty.ToString("F4")); _motorWinding.SetOutputPowerAndPolarity(duty); CurrentVelocity = duty; }
/// <summary> /// Reduces a given angle to a value between -π and +π radians. /// </summary> /// <param name="radians">The angle in radians.</param> /// <param name="tolerance">The tolerance.</param> /// <returns>System.Double.</returns> public static double WrapAngleWithinPositiveNegativePi(double radians, double tolerance = Numbers.ZeroTolerance) { double wrappedAngleWithinTwoPi = WrapAngleWithinTwoPi(radians, tolerance); if (NMath.Abs(wrappedAngleWithinTwoPi) > Numbers.Pi) { return(-NMath.Sign(wrappedAngleWithinTwoPi) * (Numbers.TwoPi - NMath.Abs(wrappedAngleWithinTwoPi))); } return(wrappedAngleWithinTwoPi); }
public static ITransform2 EvaluateTransform(Point2d point0, Point2d point1, double radius0, double radius1, double a) { // Correccion sobre los radios. if (SysMath.Sign(radius1) != SysMath.Sign(radius0)) { if (double.IsInfinity(radius0)) { radius0 = SysMath.Sign(radius1) * double.PositiveInfinity; } else if (double.IsInfinity(radius1)) { radius1 = SysMath.Sign(radius0) * double.PositiveInfinity; } else { // No se permite cambio de signo en el radio. Funcionaria??? Contract.Assert(false); } } bool invertY; if (SysMath.Abs(radius0) > SysMath.Abs(radius1)) { // t positivas invertY = radius1 < 0; } else { // t negativa invertY = radius1 > 0; } // Diferencia de puntos en coordenadas reales. Vector2d v01 = point1.Sub(point0); // Desarrollo segun el radio en el punto (0) y (1). double l0_n = ClothoUtils.ClothoL(radius0, invertY, a); double l1_n = ClothoUtils.ClothoL(radius1, invertY, a); // Coordenadas en el punto (0) y (1) para una clotoide normalizada. Point2d p0_n = ClothoUtils.Clotho(l0_n, invertY, a); Point2d p1_n = ClothoUtils.Clotho(l1_n, invertY, a); Vector2d v01_n = p1_n.Sub(p0_n); // Rotacion de v01_n -> v01. double r = v01_n.AngleTo(v01); // Transformacion a aplicar. return(Transform2.Translate(point1.X - p1_n.X, point1.Y - p1_n.Y) .Concat(Transform2.Rotate(p1_n.X, p1_n.Y, r))); }
/// <summary> /// Reduces a given angle to a value between π and -π. /// </summary> /// <param name="radians"></param> /// <returns></returns> public static double WrapAngle(double radians) { int revolutions = (int)NMath.Floor(radians / Numbers.TwoPi); double wrappedAngle = radians - revolutions * Numbers.TwoPi; if (NMath.Abs(wrappedAngle) > Numbers.Pi) { return(-NMath.Sign(wrappedAngle) * (Numbers.TwoPi - NMath.Abs(wrappedAngle))); } return(wrappedAngle); }
/// <summary> /// Converts to a date time. /// </summary> /// <param name="cache"></param> /// <param name="unadjustedDate"></param> /// <param name="businessDayAdjustments"></param> /// <param name="offset"></param> /// <param name="nameSpace"></param> /// <returns></returns> public static DateTime ToAdjustedDate(ICoreCache cache, DateTime unadjustedDate, BusinessDayAdjustments businessDayAdjustments, Offset offset, string nameSpace) { if (DayTypeEnum.Business != offset.dayType && DayTypeEnum.Calendar != offset.dayType) { throw new NotSupportedException( $"Only {DayTypeEnum.Business}, {DayTypeEnum.Calendar} day types supported of Offset type."); } IBusinessCalendar businessCalendar = BusinessCenterHelper.ToBusinessCalendar(cache, businessDayAdjustments.businessCenters, nameSpace); int periodMultiplier = Int32.Parse(offset.periodMultiplier); // offset using calendar days // switch (offset.dayType) { case DayTypeEnum.Business: { switch (offset.period) { case PeriodEnum.D: { // Advance using given number of business days // int periodMultiplierSign = Math.Sign(periodMultiplier); DateTime offsetedDate = unadjustedDate; while (periodMultiplier-- > 0) { offsetedDate = offsetedDate.AddDays(periodMultiplierSign); offsetedDate = businessCalendar.Roll(offsetedDate, businessDayAdjustments.businessDayConvention); } return(offsetedDate); } default: throw new NotSupportedException( $"{offset.period} not supported in conjunction with '{offset.dayType} day type'"); } //~switch(offset.period) } case DayTypeEnum.Calendar: { // Convert offset to period. DateTime adjustedDate = offset.Add(unadjustedDate); return(adjustedDate); } default: { throw new NotSupportedException( $"Only {DayTypeEnum.Business}, {DayTypeEnum.Calendar} day types supported of Offset type."); } } }
/// <summary> /// Moves one step in the indicated direction. /// </summary> /// <param name="direction"> /// A signed integer value indicating The direction to step. Any positive value results in a single forward step. /// any negative value results in a backward step. Zero results in no step. /// </param> public void MoveOneStep(int direction) { var safeDirection = Math.Sign(direction); if (safeDirection == 0) { return; // Not moving. } RaiseBeforeStep(this); stepper.PerformStep(safeDirection); currentPosition += safeDirection; if (currentPosition > limitOfTravel || currentPosition < 0) { WrapPosition(); } }
/// <summary> /// Moves the motor to the specified position. /// </summary> /// <param name="target">The target position, in steps.</param> public void MoveToTargetPosition(int target) { var moveDirection = (short)Math.Sign(target - currentPosition); if (moveDirection == 0) { AllStop(); return; } lock (motorUpdateLock) { targetPosition = target; regulating = false; StartStepping(moveDirection); } }
/// <summary> /// Obtiene el centro de la circunferencia que pasa por los 2 puntos, con el radio indicado. /// Dependiendo del criterio (leftRule), se interpreta el signo del radio: /// Si leftRule entonces el radio se multiplica por la normal a la izquierda (leftNormal) para obtener el centro de la /// circunferencia. /// Si rightRule (!leftRule) entonces el radio se multiplica por la normal a la derecha (rightNormal) para obtener el /// centro de la circunferencia. /// Clip utiliza un criterio rightRule. /// <p /> /// Criterio rightRule: /// <c><![CDATA[ /// _ _ /// _ / \c /// _/ O pf O /// _/ / / \ /// / _/ radio - _/ | /// / /| radio + <-- /| | /// | / --> / / /// / / / _/ /// |/ / _/ /// O pi O__/ /// \ _/ /// ]]></c> /// <![CDATA[ /// p1 a/2 pm a/2 p2 /// x---------+-------->x /// \ | / /// \ | / /// \ | / /// \ |b / /// \ | / r /// \ | / /// \ | / /// \ | / /// \|/ /// pc /// ]]> /// Teniendo como dato p1, p2 y r, tenemos que obtener el centro del circulo que pasa por /// p1 y p2, con radio r. /// Con el vector 1-2 obtenemos la distancia a. /// b es calculado mediante la fórmula b = raizcua(r * r + a/2 * a/2). /// Creamos un vector perpendicular al 1-2 a una distacion a/2 desde p1 y obtenemos /// el punto central de la circunferencia. /// Con este dato y conociendo el radio ya simplemente calculamos la esquina del rectangulo. /// Si el radio es positivo, avanza en sentido contrario a las agujas del reloj. /// Si el radio es negativo, avanza en sentido de las agujas del reloj. /// <![CDATA[ /// + p2 /// /|\ /// | /// /____ | ____\ /// \ \___ | ___/ / /// \__ | __/ /// \_ | _/ /// radio - \ | / radio + /// (giro \ | / (giro horario) /// antihorario) \|/ /// | /// + p1 /// ]]> /// </summary> /// <exception cref="CalculoImposibleException"> /// Indica que no se puede calcular el /// centro. /// </exception> public static Vec2d EvaluateCenter(Vec2d pt0, Vec2d pt1, double radius, bool leftRule) { // Vector direccion normalizado y longitud. Vec2d dir = pt1.Sub(pt0); double a = dir.Length; if (a.EpsilonEquals(0)) { throw new Exception("CalculoImposible: Puntos coincidentes."); } dir = dir.Div(a); // Punto medio. Vec2d pm = vecMath.Interpolate(pt0, pt1, 0.5); // Se tratan radios erroneos que no permitan generar un circunferencia. double v = radius * radius - a * a / 4; if (v.EpsilonEquals(0)) { return(pm); } if (v < 0) { throw new Exception("CalculoImposible: Radio erroneo."); } double b = SysMath.Sign(radius) * SysMath.Sqrt(v); Vec2d normal; if (leftRule) { // Vector normal a la izquierda. normal = vecMath.PerpLeft(dir); } else { // Vector normal a la derecha. normal = vecMath.PerpRight(dir); } Vec2d vectorm1 = normal.Mul(b); return(pm.Add(vectorm1)); }
private void Sign_() { new Validator("sign") .OneParameter() .FloatOrInteger() .Validate(this.stack); var x = this.Pop(); IValue y = x switch { Value.Int i => new Value.Int(i.Value.Sign), Value.Float f => new Value.Float(M.Sign(f.Value)), _ => throw new NotSupportedException(), }; this.Push(y); }
/// <summary> /// Calcula el radios de la curva. /// </summary> public static double ClothoRadius(double s, bool invertY, double a) { double radius; if (s.EpsilonEquals(0)) { radius = MathUtils.SafeSign(s) * double.PositiveInfinity; // Punto de inflexion, puede ser (+) o (-). } else { radius = (a * a / s); if (SysMath.Abs(radius) >= MAX_RADIUS) { radius = SysMath.Sign(radius) * double.PositiveInfinity; } } if (invertY) { radius = -radius; } return(radius); }
public static int Math_Sign(ILuaState luaState) { luaState.PushNumber(Math.Sign(luaState.ToNumber(-1))); return(1); }
public static long Sign(long n_value) { return(CSMath.Sign(n_value)); }
public static long Sign(double d_value) { return(CSMath.Sign(d_value)); }
/// <summary> /// Returns the sign of the number: -1, 0, or 1. /// </summary> /// <param name="integer">A number.</param> /// <returns name="sign">The sign of the number: -1, 0, or 1.</returns> public static long Sign(long integer) { return(CSMath.Sign(integer)); }
/* DISABLE - LC - 070 Pre-release * public static double Round(double value, int digits, MidpointRounding mode) * { * return CSMath.Round(value, digits, mode); * } */ /// <summary> /// Returns the sign of the number: -1, 0, or 1. /// </summary> /// <param name="number">A number.</param> /// <returns name="sign">The sign of the number: -1, 0, or 1.</returns> public static long Sign(double number) { return(CSMath.Sign(number)); }
// Inverse Cosecant public static double Arccosec(double x) { return(MathObj.Atan(MathObj.Sign(x) / MathObj.Sqrt(x * x - 1))); }
// Inverse Hyperbolic Cosecant public static double HArccosec(double x) { return(MathObj.Log((MathObj.Sign(x) * MathObj.Sqrt(x * x + 1) + 1) / x)); }
/// <summary> /// Trace should be in map coordinates /// Trace is aborted when nodeCallback is true. /// </summary> /// <param name="trace"></param> /// <returns></returns> public bool Traverse(RayTrace trace, Func <Point3, bool> nodeCallback) { //trace.Ray = new Ray(trace.Ray.Position - GridOffset, trace.Ray.Direction); //TODO: ALLWAYS RETURNS TRUE Vector3 tDelta; tDelta.X = NodeSize / M.Abs(trace.Ray.Direction.X); // how far we must move in the ray direction before we encounter a new voxel in x-direction tDelta.Y = NodeSize / M.Abs(trace.Ray.Direction.Y); // same but y-direction tDelta.Z = NodeSize / M.Abs(trace.Ray.Direction.Z); var endDist = trace.End; //Only support ints!! if (endDist > int.MaxValue) { endDist = int.MaxValue; } var start = trace.Ray.Position + trace.Ray.Direction * trace.Start; var end = trace.Ray.Position + trace.Ray.Direction * endDist; var dir = trace.Ray.Direction; // We work in grid coordinates, with grid size rescaled to 1 start -= GridOffset; end -= GridOffset; start /= NodeSize; end /= NodeSize; // start voxel coordinates Point3 pos = new Point3((int)start.X, (int)start.Y, (int)start.Z); // end voxel coordinates Point3 endPos = new Point3((int)end.X, (int)end.Y, (int)end.Z); // decide which direction to start walking in var step = new Point3(M.Sign(dir.X), M.Sign(dir.Y), M.Sign(dir.Z)); // Distance to the next intersection Vector3 dist; // calculate distance to first intersection in the voxel we start from dist = pos; if (dir.X > 0) { dist.X = dist.X + 1; } if (dir.Y > 0) { dist.Y = dist.Y + 1; } if (dir.Z > 0) { dist.Z = dist.Z + 1; } Vector3 dirInverse = new Vector3(1 / dir.X, 1 / dir.Y, 1 / dir.Z); dist -= start; //dist = Vector3.Modulate(dist, step.ToVector3()); Signs are in the dirInverse :)) dist = Vector3.Modulate(dist, dirInverse * NodeSize); if (dir.X == 0) { dist.X = float.PositiveInfinity; } if (dir.Y == 0) { dist.Y = float.PositiveInfinity; } if (dir.Z == 0) { dist.Z = float.PositiveInfinity; } bool reachedX = false, reachedY = false, reachedZ = false; while (true) { if (nodeCallback(pos)) { break; } if (step.X > 0) { if (pos.X >= endPos.X) { reachedX = true; } } else if (pos.X <= endPos.X) { reachedX = true; } if (step.Y > 0) { if (pos.Y >= endPos.Y) { reachedY = true; } } else if (pos.Y <= endPos.Y) { reachedY = true; } if (step.Z > 0) { if (pos.Z >= endPos.Z) { reachedZ = true; } } else if (pos.Z <= endPos.Z) { reachedZ = true; } if (reachedX && reachedY && reachedZ) { break; } if (dist.X < dist.Y && dist.X < dist.Z) { // progress X pos.X += step.X; dist.X += tDelta.X; } else if (dist.Y < dist.Z) { // progress Y pos.Y += step.Y; dist.Y += tDelta.Y; } else { // progress Z pos.Z += step.Z; dist.Z += tDelta.Z; } } return(true); }