My first post here and somewhat new to VB.NET, so I'm aware that I may breach some protocols. So please be patient.
A bit of background on what I'm trying to do. I've created a Windows form with a picturebox that the user can draw objects on (representing walls, doors, etc). The coordinates for the objects are saved in a SQL backend (think of it as vector drawing in a Paint like interface). The next step is to move a light source (like a person) walking through the object. I've created a light polygon in SQL representing a crude 2D raytrace and created a difference of this from the mat's polygon. Essentially this difference represents the light paths where objects can be seen.
The last step, and the one I'm stuck on, is how to display the final geometry I create (a complex curvepolygon) on the picturebox which will essentially cover up the objects that are not lit by the light source yet. At it's most basic, how do you import a geometry from SQL and then display it in a picturebox in a windows form/picturebox.
Thanks and appreciate any help. Bear in mind that I'm somewhat new to .NET, and am using this project as a way to teach myself VB.NET and SQL.
A little disappointed that there is nobody that can answer this question, but it happens. So I came up with a workaround that while not ideal, will hopefully help someone else stuck in the same situation. Maybe someone will see this and come up with a more elegant solution.
So once I have my final "shadow" polygon, I can't find a VB.NET solution to draw it as is, but that doesn't mean I can't convert it to a format that is possible to draw in a picturebox. Here's the code I came up with:
Private Sub createShadows()
Dim myPen As Pen
Dim myBrush As Brush
Dim myPoints As Point()
Dim listPoints As New List(Of Point)
Dim x As Double
Dim y As Double
' Convert the complex shape into a polygon shape in SQL and bring all the vertex
' points into VB and put into a string variable (curBlack)
mConn.Open()
Dim cmd = New SqlCommand("Select CurrentBlack.STCurveToLine().STAsText() From tbl_Map_Master Where MapID = " &
cmbDN.SelectedItem(0), mConn)
Dim curBlack As String = cmd.ExecuteScalar
mConn.Close()
' Now parse the vertex points from SQL format into a set of VB points
curBlack = curBlack.Replace("POLYGON ((", "").Replace(")", "") & ",,"
While curBlack.Length > 1
x = CInt(Strings.Left(curBlack, InStr(curBlack, " "))) * iZoom + centerX
curBlack = Strings.Right(curBlack, Len(curBlack) - InStr(curBlack, " "))
y = CInt(Strings.Left(curBlack, InStr(curBlack, ",") - 1)) * iZoom + centerY
curBlack = Strings.Right(curBlack, Len(curBlack) - InStr(curBlack, ",") - 1)
listPoints.Add(New Point(x, y))
End While
myPoints = listPoints.ToArray
' Now use the points array to draw a filled polygon
myPen = New Pen(Drawing.Color.White, 0)
myBrush = New SolidBrush(Color.FromArgb(170, 0, 0, 0))
Dim myGraphics As Graphics = pbDN.CreateGraphics
myGraphics.DrawPolygon(myPen, myPoints)
myGraphics.FillPolygon(myBrush, myPoints)
End Sub
As I said, this is not the ideal solution, so it slows things down a bit performance wise, but it works. I'm sure being a VB.NET amateur, heck I can't even get the code sample to look right in here, even the current code is not optimal, but it gets the job done. Hope someone finds this helpful.
Related
Having Chart1 in VB.NET Application , how to draw points slowly and smoothly?
Trying to find out answer before posting a question; it looks users looking for fast chart for performance, but for demonstration reasons I am looking for a way to chart data slowly.
Having this code works but not smoothly and I am not sure how it will work for 1K of points for example , also how to give user choice of speeding/slowing the chart drawing.
Module Module1
Function SlowChart() As Boolean
' ... some code
While dr.Read ' reading x,y from datareader
Dim x As DateTime = CType(dr.Item(3), DateTime)
Dim y As Integer = CType(dr.Item(4), Integer)
Chart1.Series(0).Points.AddXY(x, y)
Chart1.Update()
Threading.Thread.Sleep(300) ' pause drawing; but looks like app hanging a little
End While
'...somecode
Return True
End Function
End Module
Update: Update code structure.
Thank you
I am working on this.. the locations of the marker is in the database..
this is not google's API.
this is GMap.Net for windows.
this is the code..
For Each dtrow In markerDtable.Rows
Dim marker As New GMapMarkerGoogleGreen(New PointLatLng(dtrow("Latitude"), dtrow("Longitude")))
markersOverlay.Markers.Add(marker)
Next
I don't really understand so much, just experimented on code to get their supposed to be latlng and magically it appeared how I wanted it.
how can I make that look like this.. (this is only an emulation, I just dragged the form to what place I want them to be)
only form2 and I only need its instances.. when I click the marker, form2 appears right beside it.
UPDATE: I have my coordinates, but how can I make them appear like that? from my late versions, I use this.. form2.Location = marker.LocalPosition + New Point(20, -240) - to offset
but that code is pre-defined, hard coded. and that's not my goal. I want it on a sub, just like the code above (for markers) thank you for helping.
UPDATE2: current code - shows the three forms, but does not go to the location of the markers
For Each dtrow In markerDtable.Rows
Dim marker As New GMapMarkerGoogleGreen(New PointLatLng(dtrow("Latitude"), dtrow("Longitude")))
markersOverlay.Markers.Add(marker)
Dim f As New Form2
f.Location = marker.LocalPosition
f.Show()
Next
I have been playing around with some code, and I have made easily 50+ controls that all are labeled: PictureBox[XCoordinate]_[YCorrdinate] (Replacing the brackets and contents with the coordinates of them on a little grid I made.)
The problem with this is it is a real pain to use a control when doing loops to update all the picture boxes. I want to know how to do code like:
'This code assumes that the picture boxes are all initialized.
Dim XCoordiante As Integer = 5
Dim YCorrdinate As Integer = 2
PictureBox[XCoordinate]_[YCoordiante].Image = [Put Image Here]
I am going to put this within a loop. Is there a way that I can do this without manually typing it all and risking missing something within a case statement? And also, I would have to retype it for every different kind of change I want to make (ex: tag or error image).
Would a pointer somehow help? I don't really know how to do this, but it would be really helpful if possible.
When you create them, save them to a List:
Private pList As New List(Of PictureBox)
Dim pic As New PictureBox
With Pic
.Location = ...
' etc
End With
Me.Controls.Add(pic)
pList.Add(pic)
Assuming they are created in some sort of order:
For n As integer = 0 To pList.Count = 1
' add code to look at Plist(n).X and .Y to determine what to do (?)
Plist(n).Image = ...
Next n
If there is more info to capture, create a custom class of a PicBox and the other info, and make the list a List(Of myPicClass).
I'm using netzero hardware to manage the contents of a number of monitors. My present solution creates a form in VB.Net that has a pixel offset corresponding to where I've placed the Monitors in display management in the control panel. Each monitor has a dedicated form, and in each form are various objects.
The annoyance is that each form must be individually created (so far as I know) at design time. I can't make an array of forms, coupled with an array of offsets and assign all the properties through code.
There ought to be a way to do this...it would simplify my coding and project management.
What I see on MSDN is either over my head or not helpful.
I haven't tested this in hardware yet, but it does compile w/o error:
Public Sub makeform()
Dim MonitorForm(21) As Form
Dim MPictureBoxes(21) As PictureBox
Dim a As Integer
For i As Integer = 0 To n 'up to 21
MonitorForm(i) = New Form
MonitorForm(i).Name = "Form" & (i + 1)
MonitorForm(i).Text = "Form" & (i + 1)
MonitorForm(i).Controls.Add(MPictureBoxes(i))
MonitorForm(i).Location= new Point (x(i), y(i))
With MPictureBoxes(i)
.Name = "Picture Box " & Convert.ToString(i)
.Image = Image.FromFile(CurrentPic(i))
.Location = New System.Drawing.Point(0, 0)
.Size = New Size(1920, 1080)
' Note you can set more of the PicBox's Properties here
End With
Next
End Sub
Where I had gone wrong in my attempts at this was trying to do it this way
Dim Monitor(21) as New Form
That doesn't work, and the difference between Dim Monitor(21) as Form followed by monitor(i)= new Form
was simply too subtle for my present understand of classes, namespaces etc.
.
Well, I've had to give up on this approach and go back to creating n forms at design time (which means that they have names of form2...form22, putting each of them at manual start positions in design mode. There just doesn't seem to be a way to do this with an array of forms. So the code I have built around the messiness of forms2...forms22 works just fine, it's just going to be messy to maintain and elaborate on.
The solution to this may lie in system.screen classes, but the documentation on this is too advanced for me and I'm not finding good code examples for anything other than extracting data about how many screens there are - nothing about writing to them.
This is very easy in code. You want to make many instances of the same form. In this case, I have created a form in the designer called frmTest and I create many instances in code called frmNew:
Public Sub Main()
For x = 100 To 400 Step 100
For y = 100 To 700 Step 200
Dim frmNew As New frmTest
frmNew.Show()
frmNew.Top = x
frmNew.Left = y
frmNew.Height = 100
frmNew.Width = 200
Next
Next
End Sub
I have just used two loops to increment x and y values, but you could do this from a database or config file easily enough.
I am working in VB 2008. I have used a List(Of Point) data type to store coordinates of certain pixel values from a bitmap:
'This code is in a loop
Dim bpCoordinates As New List(Of Point)
If pixelClr > 72 Then
bpCoordinates.Add(New Point(FrameNumber, y))
End If
I want to calculate the slope between the stored points in the list using (y2 - y1)/(x2 - x1).
The problem I have is accessing the points in my list. I don't how to do this.
I looked online and can't find any way of extracting the individual coordinate points from the list. Any suggestions. Thanks.
If they're listed in a List, you can access element directly like you would in an array - although this is inefficient.
'Returns the nth list element
Dim p As Point = bpCoordinates(n)
Storing it in an array would be much better, especially if your list is long.
Dim pointArray As Point() = bpCoordinates.ToArray
Just iterate through your list or array normally afterwards.
Dim slope As Double
For index As Integer = 0 To pointArray.Length - 1
slope = (pointArray(index + 1).Y - pointArray(index).Y) / (pointArray(index + 1).X - pointArray(index).X)
'Do fun stuff with slope
Next