Calculo niveles

Iniciado por Meta, 31 Julio 2020, 23:50 PM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Hola:

Tengo esta barra que pone de 0 % al 100 %.

0%     19 %                                                                  95 %        100%
|--------|-----------------------------------------------------------|--------------|

Mejor imagen de abjo.



Dentro de Windows Form incluyo la barra progressBar y el trackBar para regular una variable.

Internamente del programa, hay dos variables, una que pone 19 y otra variabe que pone 95. Esas con constantes.

Internamente una variable es capaz de moverse del 19 al 95. En otra variable indica que es un 0 al 100 %.

Por ejemplo, si con el trackBar lo pongo al valor 95, en un label tiene que indicar que estoy al 100.

Internamente funciona del 19 al 95 y cara del usuario lo ve como si fuera del 0 al 100 %.

Código que he hecho hasta ahora y no me funciona.
using System;
using System.Windows.Forms;

namespace Regular_nivel_batería_01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            progressBar1.Value = (trackBar1.Value - 19) * 100 / (95 - 19);
            //progressBar1.Value = trackBar1.Value;
            label_Porcentaje.Text = trackBar1.Value.ToString() + " %";
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Valores del trackBar.
            trackBar1.Maximum = 100;
            trackBar1.Minimum = 0;
            trackBar1.SmallChange = 5;
            trackBar1.Value = 19;

            // Valores barra de progreso.
            progressBar1.Maximum = 95;
            progressBar1.Minimum = 19;
            progressBar1.Step = 5;
            progressBar1.Value = trackBar1.Value;
        }
    }
}


¿Es posible hacerlo?

Saludos.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Serapis

#1
Son simples matemáticas, y al caso condicionarlas es relativamente fácil.

De entrada debes mantener un valor absoluto:

0....n
Siendo 'n' el valor tan grande como se precise.
Luego se tiene un limitador (limite') que si va del 0 al 99, pués son 100 valores y si va del 0 al 100 son 101 valores.
Entonces se calcula la razón por la que a cada unidad de 'n', le corresponde un valor de 'limite', el cual logicamente tendrá decimales (si no son múltiplos).

razon = (rangoAbsoluto / rangoRelativo)
razon = ((n-inf+1) / (limiteSuperior-Limiteinferior + 1))


En el código vas procesando lo que sea, imaginemos la lectura de 2856 ficheros (0 al 2855)... y vamos por el 1500...

n = (2855-0+1) = 2856
limite = (100-0+1) = 101
razon = (2856 / 101) = 28'27

Si hay bucles (iterativos o recursivo) y los valores no cambian, el cálculo de la razón es preferible hacerlo previamente...(basta calcularlo una sola vez), aunque si no es mucho cálculo, tampoco podría suponer una sobrecarga...

Y luego dentro del bucle la transformación (interpolación) de 'n' al porcentaje equivalente , será el cálculo inverso:
valorRelativo = (valorActual / razon)
progreso.Value = (numFile / razon)
progreso.Value = (1500 / 28'27) = 53'05aprox...




Bien si lo tienes claro hasta aquí, hacer lo que quieres, es repetir lo mismo, es decir es volver a relativizar un valor dentro del previo relativizado.
Así el de antes que era relativo, hace aquí las veces de absoluto y el relativo (0-100) ahora se mueve en ese nuevo rango entre 19 y 95.


razon2 = ((95-19+1) / 101) = 0'7623

Aplicando el valor recién obtenido de 53'04622
progreso.Value = (actual / razon2)
progreso2.Value = ((53'04622-19) / 0'7623) = 44'658


Como hay 2 extremos con valores fijos, debe condicionarse:

Si (progreso.value < 19) luego
   progreso2.value = 0
O si (progreso.value > 95) luego
   progreso2.value = 100
Y Si no
   progreso2.value = ((progreso.value - limiteinferior) / razon2)
Fin si


..y eso es todo...
Nota que las 2 'forumulas' en rojo, son la clave, y los condicionantes del código (previo a esta línea)simplifican el caso anidado con límites fuera de rango fijos a valores limites.

Adjunto un par de imágenes y un código rápido en vb6 (que para esto se presta muy bien...).
Nota que el cálculo de la razón la he puesto  'enlinea', para captura todo el código completo, pero si los limites de cada 'scroll/progreso', no cambian pueden precalcularse previamente en alguna función aparte...

Una captura con los valores justo cuando el 'interno' pasa de 0.



Otra captura con el valor 1500, y con el valor justo antes de alcanzar el 100% del 'interno'

Meta

Muchas gracias. Lo pruebo y confirmo.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Meta

Buenas:

Algo no anda bien o no he entendido.
Código (csharp) [Seleccionar]
using System;
using System.Windows.Forms;

namespace Regular_nivel_batería_01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int razon2 = ((95 - 19 + 1) / 101);

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            progressBar1.Value = (trackBar1.Value / razon2);

            if (progressBar1.Value < 19)
            {
                progressBar1.Value = 0;
            }
            else if (progressBar1.Value > 95)
            {
                progressBar1.Value = 100;
            }
            else
            {
                progressBar1.Value = (progressBar1.Value - 19) / razon2;
            }

            //progressBar1.Value = trackBar1.Value;
            //label_0_al_100.Text = trackBar1.Value.ToString() + " %";
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Valores del trackBar.
            trackBar1.Maximum = 100;
            trackBar1.Minimum = 0;
            trackBar1.SmallChange = 5;
            trackBar1.Value = 19;

            // Valores barra de progreso.
            progressBar1.Maximum = 100;
            progressBar1.Minimum = 0;
            progressBar1.Step = 5;
            progressBar1.Value = 19;
        }
    }
}


Por ahora he hecho esto.

Gracias.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Serapis

#4
Citarint razon2 = ((95 - 19 + 1) / 101);
Si haces las cuentas, el resultado arroja el valor:  0'7623...
Ahora, si tu declaras la variable de tipo entero, pués lógicamente se redondea a 0... una división por 0, dará error... y aunque no diera error (caso de un valor mayor), se perdería precisión en los cálculos al redondear...
CitarSingle razon2 = (77f / 101f);  // toda vez que (95-19)+1= 77

Son simples matemáticas, pero aplicado con programación hay que considerar decimales y hacer las conversiones oportunas de un valor con decimales a un valor entero allí donde se precisen, etc...

Por otro lado el código dentro del evento Scroll del trackbar, no está bien... haces una asignación inicial y luego la cambias... sujeto al valor acabado de asignar... ¿¿¿...???

Algo como esto sería lo acorde...
Código (C#) [Seleccionar]

private void trackBar1_Scroll(object sender, EventArgs e) {      
           if (trackBar1.Value < 19)            {
               progressBar1.Value = 0;   }
           else if (trackBar1.Value > 95)            {
               progressBar1.Value = 100;     }
           else             {
               progressBar1.Value = Convert.ToInt32((trackBar1.Value - trackBar1.Minimum) / razon2);
           }
           label2.Text = Convert.ToString(trackBar1.Value);
           label1.Text = Convert.ToString(progressBar1.Value);
       }


Para terminar... (ya desde entonces), no me queda claro quien debe recorrer de 0 a 100 y quien de 19 a 95, que dicho sea de paso, para explicar no importa, pero al aplicar si... como eres tú el interesado y eres tú el que sabe cual debe recorrer hasta donde, (pienso yo y espero que no en balde), que si está al revés, sabrás solucionarlo, pués se trarta en todo caso de matemáticas...



p.d.: Voy a ver si termino de aclararme, porque en algunas partes parece que es un control el que varía en un rango y en otras partes en el otro.

Citar
Dentro de Windows Form incluyo la barra progressBar y el trackBar para regular una variable.

Internamente del programa, hay dos variables, una que pone 19 y otra variabe que pone 95. Esas con constantes.

Internamente una variable ... del 19 al 95. En otra ... 0 al 100 %.

Por ejemplo, si con el trackBar lo pongo al valor 95, en un label tiene que indicar que estoy al 100.

Internamente funciona del 19 al 95 y cara del usuario lo ve como si fuera del 0 al 100 %.
Voy a suponer que es el trackbar el que discurre de 19 a 95, para que en el progressbar se vea del 0 al 100...

Entonces lo primero es fijar dichos valores en el control.
Y como una imagen vale más que 1000 palabras... adjunto una:


Nótese, que como hemos prefijado los límites del trackbar al rango 19-95, los valores  fuera de dicho rango ya no se van a dar (la lógica interna del control se encarga de ello), luego el código queda aún más simple, observa el cambio (del código) en la siguiente imagen:


Código (C#) [Seleccionar]

private void trackBar1_Scroll(object sender, EventArgs e) {      
   progressBar1.Value = Convert.ToInt32((trackBar1.Value - trackBar1.Minimum) / razon2);
   label2.Text = Convert.ToString(trackBar1.Value);
   label1.Text = Convert.ToString(progressBar1.Value);
}


Meta

Hola:

Haciéndolo así tal como te he entendido.
Código (csharp,18) [Seleccionar]
using System;
using System.Windows.Forms;

namespace Regular_nivel_batería_01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int razon2 = ((95 - 19 + 1) / 101);
        //int x = Convert.ToInt32((trackBar1.Value - trackBar1.Minimum) / razon2);

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            progressBar1.Value = Convert.ToInt32((trackBar1.Value - trackBar1.Minimum) / razon2);
            label2.Text = Convert.ToString(trackBar1.Value);
            label1.Text = Convert.ToString(progressBar1.Value);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Valores del trackBar.
            trackBar1.Maximum = 100;
            trackBar1.Minimum = 0;
            trackBar1.SmallChange = 5;
            trackBar1.Value = 19;

            // Valores barra de progreso.
            progressBar1.Maximum = 100;
            progressBar1.Minimum = 0;
            progressBar1.Step = 5;
            progressBar1.Value = 19;
        }
    }
}


Me da error:
{"Intento de dividir por cero."}
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Serapis

#6
Cita de: Meta link=topic=506174.msg2227773#msg2227773
date=1599349572

Me da error:
{"Intento de dividir por cero."}

No lees... o tienes memoria de pez. Mi mensaje previo empieza con (lo primero que vi al leer tu código):
Cita de: NEBIRE en  6 Septiembre 2020, 00:10 AM
Citarint razon2 = ((95 - 19 + 1) / 101);
Si haces las cuentas, el resultado arroja el valor:  0'7623...
Ahora, si tu declaras la variable de tipo entero, pués lógicamente se redondea a 0... una división por 0, dará error... y aunque no diera error (caso de un valor mayor), se perdería precisión en los cálculos al redondear...
Son simples matemáticas, pero aplicado con programación hay que considerar decimales y hacer las conversiones oportunas de un valor con decimales a un valor entero allí donde se precisen, etc...
Solución:
CitarSingle razon2 = (77f / 101f);  // toda vez que (95-19)+1= 77


Luego, tampoco te has ajustado a lo que digo y muestro en las imágenes, y eso que he puesto flechitas y realizado la captura para que se vea esa parte...
Si un control solo tiene el rango 19-95, para que ponerle un rango fuera de rango como lo es: 0-100
Es más, justo al final he comentado, precisamente eso... que gracias a tal restricción (que es lo más crrecto), en el evento podemos ahorrarnos código (porque ya lo realiza el propio control por nosotros)...

Cita de: Meta link=topic=506174.msg2227773#msg2227773
date=1599349572


       private void Form1_Load(object sender, EventArgs e)
       {
           // Valores del trackBar.
           trackBar1.Maximum = 100; <----- el límite máximo no es 95 ?????
           trackBar1.Minimum = 0;   <--------- el límite mínimo, no es 19 ????
           trackBar1.SmallChange = 5;  <------------ porqué saltos 'pequeños' de 5, en un rango tan escueto ????
           trackBar1.Value = 19;  <----- innecesario si minimo = 19

           // Valores barra de progreso.
           progressBar1.Maximum = 100;
           progressBar1.Minimum = 0;
           progressBar1.Step = 5;       <------ para qué, esto solo sirve cuando se usa .performeStep ????
           progressBar1.Value = 19;    <---------- si va de 0 a 100, porque inicialmente debe valer 19???? valdrá o

En las imágenes puede leerse más simple y correcto:
Código (csharp,18) [Seleccionar]

       private void Form1_Load(object sender, EventArgs e)
       {
           // Valores del trackBar: 19 al 95
           trackBar1.Maximum = 95;         //100;
           trackBar1.Minimum = 19;           // 0;
           trackBar1.SmallChange = 1;        // 5;
           //trackBar1.Value = 19;

           // Valores barra de progreso: 0 al 100
           progressBar1.Maximum = 100;
           progressBar1.Minimum = 0;
           //progressBar1.Step = 5;
           //progressBar1.Value = 19;


Por favor, tómate el tiempo de leer las veces que necesites los mensajes, las respuestas han sido dadas una y otra vez.



p.d.: en realidad es muy sencillo de entender....

Imagina que tienes 77 libras esterlinas y que en euros son 101 euros... la razón sería el factor de conversión, el valor de cambio entre las monedas, como se da en 'libras' y quiere pasarse a euros, el valor de cambio será:  cambio = (libras/euros) = (77/101) = 0'7623 así 1 libra = 0'7623 euros...

Luego imagina que el banquero se queda con una tasa fija 19 libras por hacerte el cambio, así cuando vayas al banco, la 'cuenta del rankataplán' que te harán será:
euros a cobrar = ((libras a cambiar - tasa fija) / valor de cambio)
Como los euros los cobras enteros (el banco no tiene monedas sueltas), pierdes los céntimos, solo cobras euros enteros (se redondea).

95, podría entenderse como el máximo de libras (al que le restará su tasa) que el banco acepta cambiar en una operación... (algo absurdo, pero para terminar de ejemplificarlo, vale)...

Meta

Me funciona al 100 %.
Código (csharp) [Seleccionar]
using System;
using System.Windows.Forms;

namespace Regular_nivel_batería_01
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int razon2;
        //int x = Convert.ToInt32((trackBar1.Value - trackBar1.Minimum) / razon2);

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            progressBar1.Value = (trackBar1.Value - trackBar1.Minimum) * 100 / razon2;
            label_19_a_95.Text = trackBar1.Value.ToString();
            label_0_al_100.Text = progressBar1.Value.ToString();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Valores del trackBar.
            trackBar1.Maximum = 95;
            trackBar1.Minimum = 19;
            trackBar1.SmallChange = 1;
            //trackBar1.Value = 19;

            // Valores barra de progreso.
            progressBar1.Maximum = 100;
            progressBar1.Minimum = 0;
            progressBar1.Step = 1;
            progressBar1.Value = 0;

            razon2 = trackBar1.Maximum - trackBar1.Minimum;
        }
    }
}


Muchísimas gracis mi muy distinguido amigo.  ;-) ;-) ;-) ;-) ;-) ;-) ;-) ;-)
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/