By means of Mates8, graph coding becomes a bit easier.
The web page has four textboxes so the figure gets bounded to the left, right, top and bottom; and a draw button.
Additionally, a panel control will contain the image generated by the code after the button is pressed.
Mates8 grapher
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm1.aspx.vb" Inherits="mates4.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Graph</title>
<style type="text/css" media="screen">
.margin { margin-left: 9px; position:relative; top:-3px;}
.grPos { position:relative; left: 0px; top: 5px; width:<% =w %>px; height: <% =h %>px;}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Table ID="Table1" runat="server" CssClass="margin" Width="708" BackColor="#EADA90" BorderColor="#C0C0C0" BorderWidth="1">
<asp:TableRow>
<asp:TableCell>
<asp:Table ID="Table2" runat="server" Width="100%">
<asp:TableRow>
<asp:TableCell HorizontalAlign="Center">
<asp:Label ID="Label1" runat="server" Text="Left: "></asp:Label><br />
<asp:TextBox ID="tbLeft" runat="server" Width="100">-4</asp:TextBox>
</asp:TableCell>
<asp:TableCell HorizontalAlign="Center">
<asp:Label ID="Label2" runat="server" Text="Right: "></asp:Label><br />
<asp:TextBox ID="tbRight" runat="server" Width="100">4</asp:TextBox>
</asp:TableCell>
<asp:TableCell HorizontalAlign="Center">
<asp:Label ID="Label3" runat="server" Text="Bottom: "></asp:Label><br />
<asp:TextBox ID="tbBottom" runat="server" Width="100"></asp:TextBox>
</asp:TableCell>
<asp:TableCell HorizontalAlign="Center">
<asp:Label ID="Label4" runat="server" Text="Top: "></asp:Label><br />
<asp:TextBox ID="tbTop" runat="server" Width="100"></asp:TextBox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="Label5" runat="server" Text="Function 1:" ForeColor="black"></asp:Label><br />
<asp:Textbox id="f1" runat="server" Columns="18" TextMode="MultiLine" Rows="5">x^3-1</asp:Textbox>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="Label6" runat="server" Text="Function 2:" ForeColor="blue"></asp:Label><br />
<asp:Textbox id="f2" runat="server" Columns="18" TextMode="MultiLine" Rows="5"></asp:Textbox>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="Label7" runat="server" Text="Function 3:" ForeColor="green"></asp:Label><br />
<asp:Textbox id="f3" runat="server" Columns="18" TextMode="MultiLine" Rows="5"></asp:Textbox>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="Label8" runat="server" Text="Function 4:" ForeColor="red"></asp:Label><br />
<asp:Textbox id="f4" runat="server" Columns="18" TextMode="MultiLine" Rows="5">0</asp:Textbox>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell ColumnSpan="4" HorizontalAlign="Center">
<asp:CheckBox ID="chkAutoTopBottom" Text="Auto top-bottom" runat="server" Checked="true" />
<asp:Button ID="btnDraw" runat="server" Text="Draw" />
<asp:Label runat="server" ID="lblMessage" Text="" ForeColor="Red" />
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell ColumnSpan="4">
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Table ID="TableGraphic" runat="server" Height="690" Width="100%" BackColor="#FAFAFA">
<asp:TableRow>
<asp:TableCell>
<asp:Panel runat="server" ID="Panel1">
</asp:Panel>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</div>
</form>
</body>
</html>
=================================================
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Image
Imports System.IO
Partial Public Class graphic
Inherits System.Web.UI.Page
Dim nID As Int32
Const nFn As Int32 = 4
Const nDiv As Int32 = 10
Public Const w As Int32 = 650
Public Const h As Int32 = 650
Dim vMtxParser(nFn - 1) As matrixParser
Dim vPoly(nFn - 1) As Polynomial, iP As Int32
Dim oVars(nFn - 1) As VarsAndFns
Dim vIsEmptyStr(nFn - 1) As Boolean
Dim vIsPoly(nFn - 1) As Boolean
Dim vDbl(3) As Double
Dim sErrMsg As String = "Graphic n/a"
Dim min As Single = Single.MaxValue
Dim max As Single = -min
Dim cImg As HtmlImage
Dim origH, origW As Int32
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim sImagePath As String = MapPath("~/precis/images/grTable.png")
Try
cImg = New UI.HtmlControls.HtmlImage
cImg.Alt = "Graphic"
cImg.Attributes.Add("class", "grPos")
If Page.IsPostBack Then
GetGraphic(sImagePath)
Else
Try
C_session.contador( _
Page, _
Request, _
Response)
nID = C_session.getID(Page)
Catch ex2 As Exception
End Try
Using ms As New MemoryStream
Dim img As Image = Image.FromFile(sImagePath)
img.Save(ms, Imaging.ImageFormat.Png)
cImg.Attributes.Add("src", _
"data:image/png;base64," + Convert.ToBase64String(ms.ToArray))
cImg.Attributes.Add("style", "position:relative; left:20px; top: 10px;")
End Using
End If
Me.Panel1.Controls.Add(cImg)
Catch ex As Exception
lblMessage.Text = "n/a"
End Try
End Sub
Private Sub btnDraw_Click(sender As Object, e As EventArgs) Handles btnDraw.Click
'Dim sImagePath As String = MapPath("~/precis/images/grTable.png")
'GetGraphic(sImagePath)
End Sub
Sub GetGraphic(sGridImagePath As String)
Try
If Not validateInputs() Then
lblMessage.Text = sErrMsg
Exit Try
End If
Dim sFn() As String = {f1.Text, _
f2.Text, _
f3.Text, _
f4.Text}
Me.getvMtxP_and_vPoly(sFn)
' Load a square grid of ten rows
' and columns (i.e. 11 horizontal lines
' and 11 vertical lines):
Dim bmp As New Bitmap(sGridImagePath)
origH = bmp.Height
origW = bmp.Width
Dim gr As Graphics = Graphics.FromImage(bmp)
gr.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
gr.InterpolationMode = InterpolationMode.NearestNeighbor
Dim vPen() As Pen = {New Pen(Brushes.Black, 0), _
New Pen(Brushes.Blue, 0), _
New Pen(Brushes.Green, 0), _
New Pen(Brushes.Red, 0)}
Dim grPath(nFn - 1) As GraphicsPath
For i As Int32 = 0 To vIsEmptyStr.Length - 1
If Not vIsEmptyStr(i) Then
' Get function's path points:
grPath(i) = _
Me.evalFnToGraphicsPath( _
i, vDbl(0), vDbl(1), w)
End If
Next
If chkAutoTopBottom.Checked Then
vDbl(2) = max
vDbl(3) = min
tbTop.Text = vDbl(2).ToString(MathGlobal8.us)
tbBottom.Text = vDbl(3).ToString(MathGlobal8.us)
Else
max = vDbl(2)
min = vDbl(3)
End If
For i As Int32 = 0 To vIsEmptyStr.Length - 1
If grPath(i) IsNot Nothing AndAlso _
grPath(i).PathData.Points.Count Then
' Translate Y origin:
gr.TranslateTransform(0, -min, MatrixOrder.Append)
' Scale X, Y axis:
If max = min Then
Throw New Exception("n/a")
End If
gr.ScaleTransform(bmp.Width / w, _
bmp.Height / (max - min), MatrixOrder.Append)
' Add into image's Graphics gr:
gr.DrawPath(vPen(i), grPath(i))
' restore origin and scale:
gr.ResetTransform()
End If
Next
' Flip image because gr's vertical axis increments
' downwards and graphic's Y axis will increment
' upwards:
bmp.RotateFlip(RotateFlipType.Rotate180FlipX)
' Get a bigger bitmap...
Dim bmp1 As New Bitmap(bmp.Width + 125, bmp.Height + 60)
Dim gr1 As Graphics = Graphics.FromImage(bmp1)
gr1.Clear(Color.White)
' ...and copy former image to (100,50) to allow
' space on the left and top for the strings:
gr1.DrawImage(bmp, New Point(100, 50))
gr1.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
' Draw X's and Y's coordinates values as strings:
drawStrings(gr1)
' Release resources:
gr.Dispose()
bmp.Dispose()
Using ms As New MemoryStream
' Save bmp1 into memory...
bmp1.Save(ms, Imaging.ImageFormat.Png)
' ...and set, to the image control on the
' aspx page, the memory file in base64 string format:
cImg.Src = "data:image/png;base64," + Convert.ToBase64String(ms.ToArray)
End Using
' Release resources:
gr1.Dispose()
bmp1.Dispose()
Catch ex As Exception
Throw ex
'lblMessage.Text = sErrMsg
End Try
End Sub
Function validateInputs() As Boolean
Dim mP As New matrixParser
Try
' Axis' X values will be in the
' interval [vDbl(0), vDbl(1)]
' Verify tbLeft -- tbRight
' ------------------------
' eval eventual arithmetic (for ex. 2/3) ...
mP.parse(tbLeft.Text)
' ...but must reduce to a double value:
vDbl(0) = mP.retCjo(0).pRe.ToDouble
mP.parse(tbRight.Text)
vDbl(1) = mP.retCjo(0).pRe.ToDouble
If vDbl(1) < vDbl(0) Then
' If left < right, swap values:
Dim dbl As Double = vDbl(0)
vDbl(0) = vDbl(1)
vDbl(1) = dbl
ElseIf vDbl(0) = vDbl(1) Then
Return False
End If
If vDbl(1) - vDbl(0) <= 1000 * Double.MinValue Then
Return False
End If
If chkAutoTopBottom.Checked = False Then
' Axis' Y values will be in the
' interval [vDbl(2), vDbl(3)]:
' values outside these bounds
' will not be graphed.
' If not auto-Top-Bottom checked, consider
' inputs in textboxes tbTop, tbBottom.
' Verify tbTop -- tbBottom
' ------------------------
mP.parse(tbTop.Text)
vDbl(3) = mP.retCjo(0).pRe.ToDouble
mP.parse(tbBottom.Text)
vDbl(2) = mP.retCjo(0).pRe.ToDouble
If vDbl(2) < vDbl(3) Then
' If top < bottom, swap values:
Dim dbl As Double = vDbl(2)
vDbl(2) = vDbl(3)
vDbl(3) = dbl
ElseIf vDbl(2) = vDbl(3) Then
Return False
End If
If vDbl(2) - vDbl(3) <= 1000 * Double.MinValue Then
Return False
End If
Else
' If auto-Top-Bottom checked
' allow any double value:
vDbl(2) = Double.MaxValue
vDbl(3) = -Double.MaxValue
End If
Catch ex As Exception
Throw ex
'Return False
End Try
Return True
End Function
Private Sub getvMtxP_and_vPoly(sFn() As String)
Try
For i As Int32 = 0 To nFn - 1
If sFn(i) IsNot Nothing AndAlso _
sFn(i).Length Then
vMtxParser(i) = New matrixParser()
vMtxParser(i).parse(sFn(i), "", oVars(i))
' Find out if sFn is a Polynomial expression
' because, if so, evaluation will be less
' time consuming:
If vMtxParser(i).ret.exprMtx.IsPolynomial Then
vIsPoly(i) = True
vPoly(i) = vMtxParser(i).ret.curExpr.getPolynomial
End If
Else
vIsEmptyStr(i) = True
End If
Next
Catch ex As Exception
Throw ex
End Try
End Sub
Private Sub drawStrings(ByRef gr As Graphics) ' Get graph's strings
Try
Dim iv As Int32 = 0
Dim incrV As Double = (max - min) / nDiv
Dim incrH As Double = (vDbl(1) - vDbl(0)) / nDiv
Dim dist As Double = origH / nDiv
Dim fntStr As New Font("Arial Narrow", 12)
Dim ptImg As New Point(100, 30)
Dim Vert As Double = max
Dim Horiz As Double = vDbl(0)
Dim oldsX As String = " "
Dim oldsY As String = " "
Dim nDec As Int32 = 3
Dim maxDec As Int32 = 9
Dim curPos As Single = 0
For row = 0 To 10
' Left side strings:
If Math.Abs(Vert) > 1000 Then
maxDec = 0 : nDec = 0
Else
maxDec = 9 : nDec = 3
End If
Dim curDec As Int32 = nDec
Dim sX As String = ""
Do
sX = Math.Round(Vert, curDec).ToString(MathGlobal8.us)
curDec += 1
Loop While sX = oldsX AndAlso curDec < maxDec
oldsX = sX
Dim s As SizeF = gr.MeasureString(sX, fntStr)
gr.DrawString(sX, fntStr, _
Brushes.Black, _
New Point(ptImg.X - s.Width - 3, _
ptImg.Y + s.Height / 2 + dist * row))
Vert = max - incrV * (row + 1)
' Strings at the top:
If Math.Abs(Horiz) > 1000 Then
maxDec = 0 : nDec = 0
Else
maxDec = 9 : nDec = 3
End If
curDec = nDec
Dim sY As String = ""
Do
sY = Math.Round(Horiz, curDec).ToString(MathGlobal8.us)
curDec += 1
Loop While sY = oldsY AndAlso curDec < maxDec
oldsY = sY
s = gr.MeasureString(sY, fntStr)
gr.DrawString(sY, fntStr, _
Brushes.Black, _
New Point(ptImg.X - s.Width / 2 + 3 + dist * row, _
ptImg.Y - 18))
Horiz = vDbl(0) + incrH * (row + 1)
Next
gr.ScaleTransform(origW / w, _
origH / (max - min), MatrixOrder.Append)
gr.ResetTransform()
Catch ex As Exception
Throw ex
End Try
End Sub
Function evalFnToGraphicsPath(iFn As Int32, x1 As Double, x2 As Double, nPts As Int32) As GraphicsPath
Dim retGP As New GraphicsPath
Try
Dim xStep As Single = (x2 - x1) / nPts
Dim x As Single = x1
Dim y As Double
Dim i As Int32
If vIsPoly(iFn) Then
Dim Pa As Polynomial = vPoly(iFn)
y = Pa.evalPrecis(New Precis(x)).ToDouble
Dim curPt As New PointF(x, y)
Dim bClosed As Boolean = False
Dim nxtPt As New PointF
i = 1
Dim bExclude As Boolean = False
Do
x = xStep * CSng(i)
' Try-catch in case of for ex. singular points:
Try
' Evaluate Pa(x+x1):
y = Pa.evalPrecis(New Precis(x + x1)).ToDouble
Catch ex As Exception
bExclude = True
End Try
If Not bExclude AndAlso _
vDbl(3) <= y AndAlso y <= vDbl(2) Then
nxtPt.X = i
nxtPt.Y = y
retGP.AddLine(curPt, nxtPt)
min = Math.Min(min, y)
max = Math.Max(max, y)
bClosed = False
Else
' 'y' value out of bounds:
If Not bClosed Then
retGP.StartFigure()
bClosed = True
End If
End If
curPt.X = i
curPt.Y = y
i += 1
Loop While i <= nPts
Else
Dim cjo As Complex
Dim bExclude As Boolean = True ' Exclude the starting point
Dim curPt As New PointF
Dim bClosed As Boolean = True
Dim nxtPt As New PointF
Do
x = xStep * i
' Try-catch in case of for ex. singular points:
Try
' Evaluate Fn(x+x1):
cjo = vMtxParser(iFn).ret.exprMtx.getExpr(0, 0).eval_1var_DblToCjo(x + x1)
If cjo IsNot Nothing Then
If cjo.pIm.IsZero Then
y = cjo.pRe.ToDouble
Else
bExclude = True
End If
Else
bExclude = True
End If
Catch ex As Exception
bExclude = True
End Try
If Not bExclude AndAlso _
vDbl(3) <= y AndAlso y <= vDbl(2) Then
nxtPt.X = i
nxtPt.Y = y
retGP.AddLine(curPt, nxtPt)
min = Math.Min(min, y)
max = Math.Max(max, y)
bClosed = False
Else
' 'y' value out of bounds (or first)
If Not bClosed Then
retGP.StartFigure()
bClosed = True
End If
bExclude = False
End If
curPt.X = i
curPt.Y = y
i += 1
Loop While i <= nPts
End If
Catch ex As Exception
Throw ex
End Try
Return retGP
End Function
End Class
xrjf 213 Posting Whiz
xrjf 213 Posting Whiz
xrjf 213 Posting Whiz
xrjf 213 Posting Whiz
xrjf 213 Posting Whiz
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.