다음을 통해 공유


C# Triangle Solver

erview

This is a wizard-style app. that through a series of questions determines which type of Triangle Solver you need.

The solution is given to your chosen number of Decimal Places or Significant Figures, both in the solver form and as an HTML page where step by step solutions are shown, along with a scale diagram and an area calculation.

 

 

 

Depending on the answers to the questions, you are redirected to either the Pythagoras' Theorem side lengths solver, the Trigonometric Ratios solver for sides and angles, the Sine Rule solver for sides and angles, or the Cosine Rule solver which also solves sides and angles.

After entering three valid values (for sides and angles), or two valid lengths (for Pythagoras' Theorem), the Calculate button is enabled and clicking it will solve the Triangle.

The HTML Template

The step by step solution, scale diagram, and area calculation are compiled into an HTML file which is then shown in a web browser control.

This is the HTML Template:

<html>
  <body>
    <div class="heading" style="margin: 20px 50px; width:90%; border-bottom: 3px solid;  color:SteelBlue;"><h1 style="font-family:calibri; color:SteelBlue;">[placeholder1]</h1></div>
    <div style="margin: 20px 50px;"><img src="[placeholder2]"/></div>
    <div style="margin: 20px 50px;">(Full precision)</div>
    <div style="margin: 20px 50px;"><p style="display:inline;">[placeholder3]</p></div>
    <div style="margin: 20px 50px;">[placeholder4]</div>
    <div style="margin: 20px 50px;"><img src="[placeholder5]"/></div>
    <div style="margin: 20px 50px;"><img src="[placeholder6]"/></div>
    <div class="heading" style="margin: 20px 50px; width:90%; border-bottom: 3px solid; border-top: 3px solid;  color:SteelBlue;"><h1 style="font-family:calibri; color:SteelBlue; display:inline;">Area </h1><h3 style="font-family:calibri; font-style:italic; color:SteelBlue; display:inline;">(Heron's Formula)</h3></div>
    <div style="margin: 20px 50px;">(Full precision)</div>
    <div style="margin: 20px 50px;"><p>s = (a/2) + (b/2) + (c/2)</p></div>
    <div style="margin: 0px 50px;"><p style="display:inline;">s = [placeholder7]</p></div>
    <br>
    <div style="margin: 20px 50px;"><p>A = Vs(s-a)(s-b)(s-c)</p></div>
    <div style="margin: 0px 50px;"><p style="display:inline;">A = V[placeholder8]</p></div>
    <br>
    <br>   
  </body>
</html>

 

It contains eight [placeholder#] tags which are replaced dynamically in code on each occasion the HTML file is created. Within the HTML files, there are certain numbers (results) in the calculations which are shown in a larger bold font. This is achieved with an emphasize Function which wraps these numbers in HTML highlighting code:

 

private string  emphasize(decimal  d)
{
    return string.Format("<p style=\"font-weight: bold; font-size: 22px; display:inline;\">{0}</p>", d);
}

  

The Triangle Class

This is the Triangle Class which scales, centers, and plots the vertex points for the scale Triangle diagrams in the HTML output. (I had some help with the Point plotting Functions, both from other Forum members and extensive Googling):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
  
namespace cs_Triangle_Solver
{
    class Triangle
    {
        public PointF A;
        public PointF B;
        public PointF C;
  
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sideA">The length of the known side BC</param>
        /// <param name="sideB">The length of the known side AC</param>
        /// <param name="sideC">The length of the known side AB</param>
        /// <param name="angleA">The internal angle in Radians at vertex A</param>
        /// <param name="angleB">The internal angle in Radians at vertex B</param>
        /// <param name="angleC">The internal angle in Radians at vertex C</param>
        /// <remarks></remarks>
        public Triangle(decimal sideA, decimal sideB, decimal sideC, decimal angleA, decimal angleB, decimal angleC)
        {
            decimal bX = Convert.ToDecimal(Math.Cos(Convert.ToDouble(angleA)) * Convert.ToDouble(sideC));
            decimal bY = Convert.ToDecimal(Math.Sin(Convert.ToDouble(angleA)) * Convert.ToDouble(sideC));
  
            this.A = PointF.Empty;
            this.C = PointF.Add(A, new  SizeF(Convert.ToSingle(sideB), 0));
            this.B = new  PointF(Convert.ToSingle(bX), Convert.ToSingle(-bY));
  
            if (bX < 0)
            {
                this.A = PointF.Add(this.A, new  SizeF(Convert.ToSingle(-bX), 0));
                this.B = PointF.Add(this.B, new  SizeF(Convert.ToSingle(-bX), 0));
                this.C = PointF.Add(this.C, new  SizeF(Convert.ToSingle(-bX), 0));
            }
  
        }
  
        public void  ScaleToFit(decimal  maxWidthOrHeight)
        {
            float[] xCoords = {
                     this.A.X,
                     this.B.X,
                     this.C.X
              };
  
            decimal OverallWidth = Convert.ToDecimal(xCoords.Max() - xCoords.Min());
            decimal OverallHeight = Convert.ToDecimal(Math.Abs(this.B.Y));
            //B.Y is negative owing to GDI+ coordinates
  
            decimal scaleFactor = OverallWidth > OverallHeight ? maxWidthOrHeight / OverallWidth : maxWidthOrHeight / OverallHeight;
            Scale(scaleFactor);
            centreTriangle(25, 300);
        }
  
        private void  Scale(decimal  scaleFactor)
        {
            this.A = ScalePointF(this.A, scaleFactor);
            this.B = ScalePointF(this.B, scaleFactor);
            this.C = ScalePointF(this.C, scaleFactor);
        }
  
        private PointF ScalePointF(PointF pf, decimal factor)
        {
            return new  PointF(pf.X * Convert.ToSingle(factor), pf.Y * Convert.ToSingle(factor));
        }
  
        private void  centreTriangle(int  border, int  displaySize)
        {
            if (B.Y > A.Y)
                B.Y -= ((B.Y - A.Y) * 2);
            PointF[] pts = new  PointF[] {
                     A,
                     B,
                     C
              };
            int offset_X = pts.Min(p => Convert.ToInt32(p.X)) - border;
            int offset_Y = pts.Max(p => Convert.ToInt32(p.Y)) - (displaySize - border);
            A = new  PointF(A.X - offset_X, A.Y - offset_Y);
            B = new  PointF(B.X - offset_X, B.Y - offset_Y);
            C = new  PointF(C.X - offset_X, C.Y - offset_Y);
        } 
    }
}

Other Resources

See Also