示例#1
0
        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));
        }
示例#3
0
        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);
        }
示例#4
0
        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;
        }
示例#5
0
        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));
        }
示例#6
0
        /// <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);
        }
示例#7
0
        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);
                }
            }
        }
示例#9
0
 /// <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));
 }
示例#10
0
        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_);
                }
            }
        }
示例#11
0
 /// <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()));
 }
示例#12
0
        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;
        }
示例#13
0
        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;
        }
示例#14
0
        /// <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);
        }
示例#15
0
        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)));
        }
示例#16
0
        /// <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);
        }
示例#17
0
        ///  <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);
            }
        }
示例#20
0
        /// <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));
        }
示例#21
0
文件: Interpreter.cs 项目: basp/xil
        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);
        }
示例#22
0
        /// <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);
        }
示例#23
0
 public static int Math_Sign(ILuaState luaState)
 {
     luaState.PushNumber(Math.Sign(luaState.ToNumber(-1)));
     return(1);
 }
示例#24
0
文件: Math.cs 项目: zjloscar/Dynamo
 public static long Sign(long n_value)
 {
     return(CSMath.Sign(n_value));
 }
示例#25
0
文件: Math.cs 项目: zjloscar/Dynamo
 public static long Sign(double d_value)
 {
     return(CSMath.Sign(d_value));
 }
示例#26
0
 /// <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));
 }
示例#27
0
        /* 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));
        }
示例#28
0
 // Inverse Cosecant
 public static double Arccosec(double x)
 {
     return(MathObj.Atan(MathObj.Sign(x) / MathObj.Sqrt(x * x - 1)));
 }
示例#29
0
 // 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);
        }