Can't use all arguments with Shapes to control line in the GraphicsWindow - shapes

After trying a few things inside small basic to make a line follow the mouse but not move the entire line, I recently came across a problem. Originally I was trying to constantly have a line update so as it stays connected from one point to the mouse position by clearing the graphics window and redrawing a line from the bottom right to the mouse. This could not work and was to resource intensive. However, now I have come across Shape.addline and shape.move. But I'm not too sure as to how they work, from my understanding, a shape can have it's own name by doing:
[Shapename] = Shapes.addline(positions)
and then that shape can be moved using:
Shapes.move(Shapename,Coordinates)
In my case it's:
L1 = Shapes.AddLine(0,GraphicsWindow.Height,GraphicsWindow.MouseX,GraphicsWindow.MouseY)
(Drawing a line from the bottom left corner to the mouses position)
and
Shapes.Move(L1,GraphicsWindow.MouseX,GraphicsWindow.MouseY)
The only problem is that Shapes.Move only supports 3 arguments being:
shapeName
X
Y
But, when drawing the line (Shapes.AddLine), I use 4 arguments:
X1
Y1
X2
Y2
This means I can only control those two positions. So, how would you control the other two? If we can only modify X1 and Y1, is there any way of still using at least something similar to the shape.move method but be able to control the other X2 and Y2 positions? Primarily, I would like to actually Only change the X2 and Y2 positions, as I'm trying to make a line originate from one point and stay there, then alter the opposing point so that it follows the mouse, and not move the entire shape. If none of this is possible, is there any known way of moving / changing only the X2 and Y2 coordinates of a line without having to clear the entire screen?

Ah yes. These are the shortcomings of small basic. Shapes.move will not let you define a starting and ending point of a line. What you will need to do is move the center of the line in between the first point and the cursor, and the rotate it correctly. Like so:
Mouseline = Shapes.AddLine(0,0,100,0)
Shapes.Move(Mouseline,200,200)
GraphicsWindow.MouseMove = OnMouseMove
Sub OnMouseMove
XDif = (GraphicsWindow.MouseX-250)
YDif = (GraphicsWindow.MouseY-200)
If XDif <> 0 Then
MouseAngle = Math.ArcTan(YDif/XDif)
EndIf
If XDif < 0 Then
MouseAngle = MouseAngle + 3.14 '180 degrees in radians
EndIf
Shapes.Rotate(Mouseline,Math.GetDegrees(MouseAngle))
Shapes.Move(Mouseline,(Math.Cos(MouseAngle)*50)+200,(Math.Sin(MouseAngle)*50)+200)
EndSub
Another way of doing this is with the LitDev extension (http://litdev.co.uk/). It has a MoveLine(x1,y1,x2,y2) function in it.

im guessing u would alter the end of the program where it says math.cos(mouseangle) change the 200 to 0 and change the other 200 to the bottom. so if what im trying to figure out, ur trying to get the line to only project in the 1st quadrant in a cortesian plane yes?

Related

How to resize a shape using CellsSRC?

I'd like to resize a shape (a line to be specific), I know it's possible to move a line with cellsSRC using the following line :
element.CellsSRC(visSectionObject, visRowXFormOut, visXFormBeginX).result("in") = 0.1
but is it possible to change the size of a line using cellsSRC ? and how to do so ? Thank you very much in advance
I don't know what you mean by 'change the size of a line', as a line has begin and end points in Visio, and are considered one dimensional. There's a thickness, which is controlled separately.
You can use CellsU to control the begin and end points, which is just easier than knowing the SRC address. So there are four cells: BeginX, BeginY, EndX, EndY, which specify the x and y coordinates of the begin and end points.
So to move the begin point to 1,2:
element.cellsU("BeginX").formula = "1"
element.cellsu("BeginY").formula = "2"

In visual basic, is it possible to teleport my cursor to x*y coordinates (Not x,y)

So I have this program in visual basic that requires teleporting your cursor around and clicking. Kinda like an automatic cheat for a game but not really a cheat.
Anyways I want the user to set coordinates to a point, then set those coordinates to a value, then with the push of a button teleport to those coordinates.
Alright I can make him get the coordinates. I can make the cursor teleport. I can set the coordinates he got to an integer X and an integer Y so the cursor teleports there. But I have to do all that 8 times. So I need 24 integers.
I was thinking, maybe I can skip all that if I can multiply xy so lets say he sets the coordinates to 320 (x) and 72 (y). (320,72) Alright so If I multiply xy I get the pixel number on the screen that exists in that coordinate (right?)
Alright that makes it so we only have 8 integers which is much less.
But how do I make the cursor teleport to the location "X*Y" (in the case of 320*72 it is pixel number 23040).
*TL;DR is it possible to convert this Windows.Forms.Cursor.Position = New Point(320,72) into this Windows.Forms.Cursor.Position = New Point(23040 (which is 320*72))*
Is it possible?
I can't think of a way of doing it please help me. Thanks.
No. (x, y) is not equivalent to (x * y).
The reason why is obvious if you give it some thought. There are many different input values for x and y that would give the same product. For example, 6 * 1 = 6, and so does 2 * 3. Which location on the screen would 6 correspond to? The point at coordinates (6, 1), (1, 6), (2, 3), or (3, 2)?
There might be a better way of doing this, but I find the description in your question to be very difficult to understand. If all you want to do is simulate a click event at a particular location on the screen, you do not need to explicitly move the cursor there first. I'd suggest how to do that, but it is not clear what language you're using. You've tagged the question [vbscript], but then talked about Windows Forms, which doesn't exist in VBScript. If you are using VB.NET, you will probably end up P/Invoking the SendInput function. Google for code examples.
While I agree with other answers/comments, what you describe is possible, but you cannot simply multiply the x and y coordinates. You need to take the screen width into consideration:
Private Function PointToPixelNumber(pt As Point) As Integer
Return pt.Y * Screen.PrimaryScreen.Bounds.Width + pt.X
End Function
Private Function PixelNumberToPoint(pixelNumber As Integer) As Point
Return New Point(pixelNumber \ Screen.PrimaryScreen.Bounds.Width, pixelNumber Mod Screen.PrimaryScreen.Bounds.Width)
End Function
Please note that this code uses integer division (\). It also assumes that the origin is at the upper left of the screen and is zero based (i. e. the upper left coordinate is (0, 0))

How do I avoid the first(and last) column of a x-capped chart being truncated?

I've been fiddling with a chart... I set the X axis minimum value to zero. Then I used DataBindXY on the Chart.Series.First.Points to set the values passing two lists (first is a 0-based label list and other has the actual values).
Below is the result. As I highlighted by the red arrow the first column is truncated.
Microsoft made traversing the settings of a chart in the designer as simple as getting out of a maze, so I'm clueless about where to find some offset property to be set.
Edit:
Mine could be a possible duplicate of this question, but its answer is not clear to me, so I asked a new one.
If you set the X axis minimum value to -0.5, that should solve it.
GraphChart.ChartAreas[0].AxisX.Minimum = -0.5;
or try something like:
GraphChart.ChartAreas[0].AxisX.IntervalOffset = 0.5;
The reason is that the columns width is approximately 0.8 depending on the chart configuration so in your case they might span from 0.4 to 1.4, with a center point in 1

How to cut out numbers from an image dynamically?

i've got to this stage:
where i can find the numbers in the above image but i need to cut them out so i can retain the order etc. but the as the number increases the spacing changes and the position of the number?
so i think it should be a find a white PX the continue until it find a solid black col and then use the points to do a simple cut any help would be great.
A simple solution would be this:
Find the first upmost horizontal line which contains white pixels
From that line find the first horizontal line which contains only black pixels
Those two lines are your upper and lower borders.
Between this borders proceed like this:
Find the first most left vertical line which contains white pixels
From that line find the last vertical line which contains only black pixels and which comes directly after a line with white pixels.
Those two lines are your left and right borders.
The steps to separate single numbers can be performed analogously.
If you need to identify which numbers are in your picture, I recommend using specialized computer vision libraries.
Some VB.net pseudo code to get you going:
Sub FindTopBorder(image As MyImage) As Integer
For y = 0 to image.Height - 1
For x = 0 to image.Width - 1
Dim pixel = image.GetPixel(x, y)
If ('Check if pixel is white here with RGB or Color') Then
Return y
End If
Next
Next
' Just in case there are no white pixels or use an exception instead
Return -1
End Sub
I would start looking into Connected component segmentation. You find a pixel which is within a character (number). Then run the connected component algorithm which finds all connected pixels under specific set of rules (e.g. slight deviation in color, stop at hard borders etc).
http://en.wikipedia.org/wiki/Connected-component_labeling
If you can use libraries, I'm sure OpenCV or similar libraries support this out of the box.
//edit
I see you need VB.net. Probably it is easiest to port some algorithm to VB or create one yourself.
See e.g. http://www.codeproject.com/Articles/336915/Connected-Component-Labeling-Algorithm
What to expect
Input
An image containing two shapes:
Output
Now each is separated into single images.

dojox.charting: how to align the plotArea of 2 charts, one above another?

I'm trying to layout 2 linked charts, one above the other, similar to what you might see on the Google Finance page.
I can render both charts just fine, but getting the plotAreas to line up exactly is a bit of a mystery. The chart.plotArea.width of each chart seems to depend on the width of my Y axis labels. Thus the 2 charts are not the same width and have different values for chart.getCoord().l.
Right now, I'm using an offset which is manually calculated, but there must be a better way.
this.chart.render(); // top chart, getCoords().w=800
// manually set margins for lower chart to match
this.chartVol.margins.l = this.chart.offsets.l - 59 + 10;
this.chartVol.margins.r = this.chart.offsets.r - 31 + 10;
// render bottom chart
this.chartVol.render(); // bottom chart same width, getCoords().w=800
There are two simple ways to do it:
Use maxLabelSize and labelFunc. The former is the maximal label's size in pixels. The latter is a function, which takes a number, and returns a corresponding string label.
Use labels, which is an array of {value, text} objects, and include one long dummy string of desired size at the end with some bogus value.
I don't recall how to do it without custom labels, so if you feel like it is really needed, please submit an enhancement ticket.