I am writing a program to control a mobile robot. One of the things it has to do is to draw a map of the "world" as the robot senses it and apply changes in the map as it senses them.
It also has to highlight in some way the location of the robot and (ideally) the direction it points to.
I currently have an auto-updating array (100 x150) representing the map, using the following representations: 0 represents a clear path, 1 represents an obstacle.
I also have a variable containing the robot's location and next location.
What I need is to visualize it. I thought about using labels, but it is way too tedious using them, and the end result is not so pretty. My other possibility is to write all that data into an Excel spreadsheet, but then I will be back to square one: visualizing the data in an attractive way. Is there a drawing package of some sort that can do the job?
To sum it up:
Using:
- int[] MapArray //100 x 150 array representing the robot's world, and the data there is changing.
- Point[] Locations //Locations[0] is the current location, Locations[1] is the next step.
And I want to draw a map on a Windows Forms application that updates itself in a nice visual manner.
I hope my question is clear enough, don't hesitate to contact me if not!
Try Code: Drawing a Filled Rectangle on a Form (Visual C#) or something similar.
Graphics Programming Example Topics
Just write a couple of cycles which accesses every cell of an array and draws a rectangle on a form according to coords - that's the simplest way.
for(int i=0; i<100; i++)
{
for(int j=0;j<150;j++)
{
<access[i,j] and draw a rectangle with color accordingly to your contents.>
}
}
The same for the drawing location.
If you don't find any nice controls, you can always use a DataGridView with the column width = row height so that it always displays square cells. After that, just change the background color of the obstacles.
You could also look into observable collections for the map array so that the grid updates based on events rather than on timers. Make sure that you overwrite the observable collection to send the CollectionChanged event even when a cell changes its value, not only when adding/removing cells.
Related
I want to fill a selected region with a custom hatch that looks like a grid (like a chess table). I tried to use the ANSI37 pattern but its lines are too dense and I could not modify anything visually except the angle of the hatch. Also, I tried the custom hatch pattern creation of autocad but loading the file in autocad or creating a hatch from it in my code always results in error.This is my question: Is there anyway I can create a custom hatch pattern (grid like) that I can control the distance of lines of the grid? Is it possible for me to retrieve the custom hatch object later then query info of its lines? (how many lines, start points and end points, distance between them...)
? Thank you in advance.
About customize the predefined hatch pattern: It is possible to do that, however the properties of the hatch must be defined in a certain order to have actual effect, or else it will be ignored and use the default value instead.
for example: in my case, I defined the value of HatchStyle before PatternScale and PatternSpace while it should be the other way around. Thus, I receive the result from the default values.
About the custom grid lines drawing and querying: I got some ideas from these:
http://adndevblog.typepad.com/autocad/2013/07/create-hatch-objects-using-trace-boundaries-using-net.html
using the Editor.TraceBoudary() method, I can retrieve the loops I needed with the outer most loop will be the last entry in the return DBObjectCollection (a Polyline object to be precise). Then, create the region that needed to be hatched and access its RegionAreaProperty.Extends to get the bottom-left and top-right point of the rectangle that contains my newly created region. After that
, I can implement my logic to draw the lines of the grid.
Note that this method only works on 2d loops ( regions, closed polylines, lines, curves... on Oxy plane). I haven't find a way for the Editor.TraceBoundary() to work with 3d loops yet.
Still open for advices and suggestion for 3d loops and creating custom hatch from a given HatchPattern object.
I've write a program that construct a 2D matrix from txt file, and build a winforms panel with X*Y labels wich contains a char, coordinates, color and border (if select it).
it is my DrawGrid routine:
Container.SuspendLayout();
for (int y = 0; y < template.Matrix.GetLength(1); y++)
{
for (int x = 0; x < template.Matrix.GetLength(0); x++)
{
var curLabel = new LabelTemplate(template.Matrix[x, y].Content, x, y, spacing);
_templateCells.Add(curLabel);
Container.Controls.Add(curLabel);
}
}
Container.ResumeLayout();
whit it I view a txt file in my form, and select a row or columns or area with mouse, manipulate and save new text files from it getting content and coordinates from my LabelTemplate object (extends Label).
I've always test my program with a little txt files in input.
Today i've tested with a big txt file (9000 rows * 50 columns) and i've reached a maximun handles of a windows form application.
(an Win32 Exception is launched during Container.Controls.Add(curLabel)).
Googling i've found that the limit of controls in winforms application is 10000 handles.
Also view a lot of label on my form (if 10000 is a modificable value), performance are very bad (if i scroll container panel, i wait a lot of time to view results)!
There is a way or control that help me?
I think also to GDI+, but what is the right way for you? Any suggestions?
Thanks in advance
I think you should use DataGridView control.
If your amount of data is too big, you can limit the number of items and add some control to select the start of the region that you are viewing (like a NumericUpDdown or a TrackBar). Every time you change the start index, you reload your data to the DataGridView.
Sample of how to fill a DataGridView from an array: "How do I show the contents of this array using DataGridView?".
Another solution would be to use WPF, which has built-in UI Virtualization, therefore supports much bigger datasets without having any performance impact.
It is not practical to use labels for cells of a grid-like control. As agent5566 suggested, you can use DataGridView control for a fast approach or if you want full control and better performance, you can use a single UserControl and paint everything on it, handle keystrokes, simulate focus on cells (if needed) and so on.
I have a project where I need to calculate how many "widgets" i can remove from an area defined by the user.
for example, if i have a piece of paper... 13in x 23in. How many business cards I print when the business card dimensions are 5in x 3in.
I need something like this...
http://www.copel.com.py/calculadora-de-corte.html
But the best I can do is use a WrapPanel, which does a good job, but if I need to rotate an object, it leaves me with blank space. meaning that wrap panel works by rows, and each row takes the space of the largest object. leaving wastage around the smaller ones.
How do you suggest I attack this problem?
C#, WPF, XAML.!
Im creating a rpg like game, I've made a list of items that contains alot of variables like:
Item type
Name
Weight
ItemID
Dmg
I want so that when you over your mouse over an item, a tooltip will appear telling you all the variables of that item, sorta like WoW and all the other rpg games.
I've been thinking about having a rectangle texture that stays on mouse position and will only be shown when mouse over an item.
Now here comes the part where im having problem. I do not know how to scale the texture depending on the amount of text and variable length of that item, so it doesn't look wired. Also is it possible to use some sort of loop that can loop through all my variables and put them under each other?
Cheers!
/Iskalder
Are you using a Texture (or Textures) for the text or a font to display the text?
For question 1. If you're using a Texture, you can get the height and width pretty easily and adjust the scale of the tooltip accordingly. If you are using a SpriteFont, you can use SpriteFont.MeasureString to get it's dimensions.
For question 2.
As for drawing the items on top of each other, if you are using a SpriteBatch, you can specify how to layer the items in the SpriteBatch.Begin and SpriteBatch.Draw overloads. If you don't mean to layer the variables/items and just want to display them so that they appear "stacked" on top of each other, you can simply specify the origin at which to draw the item in SpriteBatch.Draw and have each subsequent item drawn at a different height (y coordinate).
Original Question
I'm using Microsoft Chart Control to display some data points as a Line. I have a Legend with custom items used to display calculated information about the line (mean average and others).
Now I've enabled IsUserSelectionEnabled which allows the user to "zoom into" a range of values and I want the legend items to be calculated on only the data points that are currently in view.
I can use the AxisViewChanged event to be notified of the view change, but what I can't figure out is how to enumerate only those DataPoint currently in view.
Update
The zoom isn't going to work for my purpose. What I discovered is that the NewPosition and NewSize properties of the AxisViewChanged event do in fact contain the precise area selected by the user, but the resulting zoom contains points outside of that area. I need more precision than that. What I need are two cursors, but the control only gives you one.
So my question now is: How do I customize this thing to add another cursor? I'm not asking just yet and if I do I'll start a new question.
Though I do still need to figure out how to translate client coords into data coords...
Updated again
I found the coord translation functions right on the Axis. Seems obvious in retrospect.
ChartArea.Axis.PixelPositionToValue (for whichever axis you need)
ChartArea.Axis.ValueToPixelPosition