2

I am trying to add values to arc and made a method for that purpose. However it looks like all of them are in one place even thought there are different coordinates given with for loop. What might be the problem?

this.RangeEnd is float 200

Here is method for adding values:

  private void OnDrawValues()
    {
      using (SKPath scalePath = new SKPath())
      {
        for (int i = 0; i <= this.RangeEnd; i += 20)
        {
          double theta = (7 * Math.PI / 4) - (i * (2 * Math.PI / 40));
          double xPos = (_gaugeRect.Width / 2) * 1.2 * Math.Sin(theta) + _drawRect.MidX - 20 / 2;
          double yPos = (_gaugeRect.Width / 2) * 1.2 * Math.Cos(theta) + _drawRect.MidY + 20 / 2;

          using (SKPaint paint = new SKPaint())
          {
            paint.Color = SKColors.White;
            paint.IsAntialias = true;
            paint.TextSize = 40;
            _canvas.DrawText(i.ToString(), (float)xPos, (float)yPos, paint);
          }
        }
      }
    } 

Here is the output:

enter image description here


EDIT:

private void OnDrawValues()
{
  using (SKPath scalePath = new SKPath())
  {
    double theta = 0;

    for (int i = 0; i <= this.RangeEnd; i += 20)
    {
      theta += (7 * Math.PI / 4) - (i * (2 * Math.PI / 40));
      double xPos = (_gaugeRect.Width / 2) * 1.2 * Math.Sin(theta) + _drawRect.MidX - 20 / 2;
      double yPos = (_gaugeRect.Width / 2) * 1.2 * Math.Cos(theta) + _drawRect.MidY + 20 / 2;

      using (SKPaint paint = new SKPaint())
      {
        paint.Color = SKColors.White;
        paint.IsAntialias = true;
        paint.TextSize = 40;
        _canvas.DrawText(i.ToString(), (float)xPos, (float)yPos, paint);
      }
    }
  }
}

produces following result:

enter image description here

10101
  • 2,232
  • 3
  • 26
  • 66
  • To make your life easier try syncfusion circular Guage. https://www.syncfusion.com/xamarin-ui-controls/xamarin-circular-gauge – Amjad S. Feb 20 '22 at 22:21
  • @AmjadS. I have checked different solutions. Syncfusion is nice one, but their components are not free and has all kind of license limitations. I would also prefer to have ability for all possible customizations in my own hands with full understand on principles how things has been made. I am not that far anymore, but this trigonometry equation is a bit tricky still for me. – 10101 Feb 20 '22 at 22:35

3 Answers3

2

I had test your code and found the value of xPos and yPos just had two kind of values. The cause of it is that (7 * Math.PI / 4) - (i * (2 * Math.PI / 40)) = 7/4PI - PI*(1,2,3...). This means the value of the Math.Sin(theta) and Math.Cos(theta) just have two kands of value. Because 2PI is a round for a circle. So you need to make the value of theta be 0~7/4PI.

Liyun Zhang - MSFT
  • 8,271
  • 1
  • 2
  • 14
1

Seeing theta is the main thing that can change in your formula:

double xPos = (_gaugeRect.Width / 2) * 1.2 * Math.Sin(theta) + _drawRect.MidX - 20 / 2;
double yPos = (_gaugeRect.Width / 2) * 1.2 * Math.Cos(theta) + _drawRect.MidY + 20 / 2;

I think you need to increment theta in the loop theta +=:

theta += (7 * Math.PI / 4) - (i * (2 * Math.PI / 40));
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
  • Thank you for an answer. I think there is still something wrong. I have updated my question with result. – 10101 Feb 21 '22 at 10:03
1

My fav author on this topic is Rod Stephens. For any drawing development definitely consider his book(s).

This should help you out with the Math (turns out its supposed to be theta += dtheta;):

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
        }

        private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            const int RADIUS_INNER = 95;
            const int RADIUS_CIRCLE = 100;
            const int RADIUS_OUTER = 105;

            // Draw the circle.
            e.Graphics.DrawEllipse(Pens.Black, 10, 10, 2 * RADIUS_CIRCLE, 2 * RADIUS_CIRCLE);

            // Draw the tick marks.
            int cx = 10 + RADIUS_CIRCLE;  // Center point.
            int cy = 10 + RADIUS_CIRCLE;
            double theta = 0;
            double dtheta = 30 * Math.PI / 180;

            for (int i = 1; i <= 360 / (double)30; i++)
            {
                int x1 = (int)(cx + Math.Cos(theta) * RADIUS_INNER);
                int y1 = (int)(cy + Math.Sin(theta) * RADIUS_INNER);
                int x2 = (int)(cx + Math.Cos(theta) * RADIUS_OUTER);
                int y2 = (int)(cy + Math.Sin(theta) * RADIUS_OUTER);
                e.Graphics.DrawLine(Pens.Red, x1, y1, x2, y2);

                theta += dtheta;
            }
        }
    }
}

enter image description here

Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321