Whether is it possible to draw ECG in VB6.0? As i am not that much familiar with VB any type of help will be appreciated.Please help me .thanks in advance.
The simplest method to do this is to use a picture box with the AutoRedraw property set to true and the ScaleMode set to vbPixels.
For each point, you calculate the Y value (dependant on the minimum and maximum allowable values). To make it scan, just increment the X value for each point you draw wrapping back to 0 when it gets to the width of the picture box (.ScaleWidth).
You can use the picture box's .Line method to blank the areas behind the current X point and the .PSet method to draw the new point.
Dim X As Long
Dim LastValue As Long
Private Sub AddPoint(ByVal Value As Long)
'Clear the line behind (for 5 pixels forward)
Picture1.Line (X, 0)-(X + 5, Picture1.ScaleHeight), vbBlack, BF
'Draw the new point and the line from the previous point
Picture1.Line (X - 1, LastValue)-(X, Value), vbGreen
Picture1.PSet (X, Value), vbGreen
'Update the last value so we can draw the line between them
LastValue = Value
'Increment the X value for the next point
X = X + 1
If X = Picture1.ScaleWidth Then X = 0
End Sub
A better method is to use an off screen picture that you update using a similar method and just update the picturebox when needed.
Related
I have an image representing an intensity graph:
intensity graph
In order to multiplicate two intensitiy graphs I need to save the coordinates of this graph. Thus, I first want to find the (middle or one border of the) line and then get its coordinates. So far I tried a few things. Which came nearest to the solution was using the LineSegmentDetector package:
library(pixmap)
image <- read.pnm(file = "graph.pgm", cellres = 1)
x <- image#grey * 255
linesegments <- image_line_segment_detector(x)
linesegments
plot(image)
plot(linesegments, add = TRUE, col = "red")
This gives me a couple of line segments:
enter image description here
However, the aim is to get one line of 1 pixel width like this:
enter image description here
Subsequently, I would need the coordinates of this graph. I would need one y value for every pixel in x direction.
I hope my problem is clear and am thankful for any help!
I have a set of 3D coordinates here. The data has 52170 rows and 4 columns. Each row represent one point. The first column is point index number, increasing from 1 to 52170. The second to fourth columns are coordinates for x, y, and z axis, respectively. The first 10 lines are as follow:
seq x y z
1 7.126616 -102.927567 19.692112
2 -10.546907 -143.824966 50.77417
3 7.189214 -107.792068 18.758278
4 7.148852 -101.784027 19.905006
5 -14.65788 -146.294952 49.899158
6 -37.315742 -116.941185 12.316169
7 8.023512 -103.477882 19.081482
8 -14.641933 -145.100098 50.182739
9 -14.571636 -141.386322 50.547684
10 -15.691803 -145.66481 49.946281
I want to create a 3D scatter plot in which each point is added sequentially to this plot using R or MATLAB. The point represented by the first line is added first, then the point represented by the second line, ..., all the way to the last point.
In addition, I wish to control the speed at which points are added.
For 2D scatter plot, I could use the following code:
library(gganimate)
x <- rnorm(50, 5, 1)
y <- 7*x +rnorm(50, 4, 4)
ind <- 1:50
data <- data.frame(x, y, ind)
ggplot(data, aes(x, y)) + geom_point(aes(group = seq_along(x))) + transition_reveal(ind)
But I cannnot find information on how to do this for 3D scatter plot. Can anyone show me how this could be done? Thank you.
This is an answer for MATLAB
In a general fashion, animating a plot (or 3d plot, or scatter plot, or surface, or other graphic objects) can be done following the same approach:
Do the first plot/plot3/scatter/surf, and retrieve its handle. The first plot can incorporate the first "initial" sets of points or even be empty (use NaN value to create a plot with invisible data point).
Set axis limits and all other visualisation options which are going to be fixed (view point, camera angle, lightning...). No need to set the options which are going to evolove during the animation.
In a loop, update the minimum set of plot object properties: XData, YData ( ZData if 3D plot, CData if the plot object has some and you want to animate the color).
The code below is an implementation of the approach above adapted to your case:
%% Read data and place coordinates in named variables
csvfile = '3D scatter plot.csv' ;
data = csvread(csvfile,2) ;
% [optional], just to simplify notations further down
x = data(:,2) ;
y = data(:,3) ;
z = data(:,4) ;
%% Generate empty [plot3] objects
figure
% create an "axes" object, and retrieve the handle "hax"
hax = axes ;
% create 2 empty 3D point plots:
% [hp_new] will contains only one point (the new point added to the graph)
% [hp_trail] will contains all the points displayed so far
hp_trail = plot3(NaN,NaN,NaN,'.b','Parent',hax,'MarkerSize',2) ;
hold on
hp_new = plot3(NaN,NaN,NaN,'or','Parent',hax,'MarkerSize',6,'MarkerEdgeColor','r','MarkerFaceColor','g','LineWidth',2) ;
hold off
%% Set axes limits (to limit "wobbling" during animation)
xl = [min(x) max(x)] ;
yl = [min(y) max(y)] ;
zl = [min(z) max(z)] ;
set(hax, 'XLim',xl,'YLim',yl,'ZLim',zl)
view(145,72) % set a view perspective (optional)
%% Animate
np = size(data,1) ;
for ip=1:np
% update the "new point" graphic object
set( hp_new , 'XData',x(ip), 'YData',y(ip), 'ZData',z(ip) )
% update the "point history" graphic object
% we will display points from index 1 up to the current index ip
% (minus one) because the current index point is already displayed in
% the other plot object
indices2display = 1:ip-1 ;
set(hp_trail ,...
'XData',x(indices2display), ...
'YData',y(indices2display), ...
'ZData',z(indices2display) )
% force graphic refresh
drawnow
% Set the "speed"
% actually the max speed is given by your harware, so we'll just set a
% short pause in case you want to slow it down
pause(0.01) % <= comment this line if you want max speed
end
This will produce:
My task is to produce the plot of a 2-dimensional function in real time using nothing but linear algebra and color (imagine having to compute an image buffer in plain C++ from a function definition, for example f(x,y) = x^2 + y^2). The output should be something like this 3d plot.
So far I have tried 3 approaches:
1: Ray tracing:
Divide the (x,y) plane into triangles, find the z-values of each vertex, thus divide the plot into triangles. Intersect each ray with the triangles.
2: Sphere tracing:
a method for rendering implicit surfaces described here.
3: Rasterization:
The inverse of (1). Split the plot into triangles, project them onto the camera plane, loop over the pixels of the canvas and for each one choose the "closest" projected pixel.
All of these are way to slow. Part of my assignment is moving around the camera, so the plot has to be re-rendered in each frame. Please point me towards another source of information/another algorithm/any kind of help. Thank you.
EDIT
As pointed out, here is the pseudocode for my very basic rasterizer. I am aware that this code might not be flawless, but it should resemble the general idea. However, when splitting my plot into 200 triangles (which I do not expect to be enough) it already runs very slowly, even without rendering anything. I am not even using a depth buffer for visibility. I just wanted to test the speed by setting up a frame buffer as follows:
NOTE: In the JavaScript framework I am using, _ denotes array indexing and a..b composes a list from a to b.
/*
* Raster setup.
* The raster is a pxH x pxW array.
* Raster coordinates might be negative or larger than the array dimensions.
* When rendering (i.e. filling the array) positions outside the visible raster will not be filled (i.e. colored).
*/
pxW := Width of the screen in pixels.
pxH := Height of the screen in pixels.
T := Transformation matrix of homogeneous world points to raster space.
// Buffer setup.
colBuffer = apply(1..pxW, apply(1..pxH, 0)); // pxH x pxW array of black pixels.
// Positive/0 if the point is on the right side of the line (V1,V2)/exactly on the line.
// p2D := point to test.
// V1, V2 := two vertices of the triangle.
edgeFunction(p2D, V1, V2) := (
det([p2D-V1, V2-V1]);
);
fillBuffer(V0, V1, V2) := (
// Dehomogenize.
hV0 = V0/(V0_3);
hV1 = V1/(V1_3);
hV2 = V2/(V2_3);
// Find boundaries of the triangle in raster space.
xMin = min(hV0.x, hV1.x, hV2.x);
xMax = max(hV0.x, hV1.x, hV2.x);
yMin = min(hV0.y, hV1.y, hV2.y);
yMax = max(hV0.y, hV1.y, hV2.y);
xMin = floor(if(xMin >= 0, xMin, 0));
xMax = ceil(if(xMax < pxW, xMax, pxW));
yMin = floor(if(yMin >= 0, yMin, 0));
yMax = ceil(if(yMax < pxH, yMax, pxH));
// Check for all points "close to" the triangle in raster space whether they lie inside it.
forall(xMin..xMax, x, forall(yMin..yMax, y, (
p2D = (x,y);
i = edgeFunction(p2D, hV0.xy, hV1.xy) * edgeFunction(p2D, hV1.xy, hV2.xy) * edgeFunction(p2D, hV2.xy, hV0.xy);
if (i > 0, colBuffer_y_x = 1); // Fill all points inside the triangle with some placeholder.
)));
);
mapTrianglesToScreen() := (
tvRaster = homogVerts * T; // Triangle vertices in raster space.
forall(1..(length(tvRaster)/3), i, (
actualI = i / 3 + 1;
fillBuffer(tvRaster_actualI, tvRaster_(actualI + 1), tvRaster_(actualI + 2));
));
);
// After all this, render the colBuffer.
What is wrong about this approach? Why is it so slow?
Thank you.
I would go with #3 it is really not that complex so you should obtain > 20 fps on standard machine with pure SW rasterizer (without any libs) if coded properly. My bet is you are using some slow API like PutPixel or SetPixel or doing some crazy thing. Without seeing code or better description of how you do it is hard to elaborate. All the info you need to do this is in here:
Algorithm to fill triangle
HSV histogram
Understanding 4x4 homogenous transform matrices
Do look also in the sub-links in each ...
Recently I was thinking about creating my own axis x/y, especially 'x', but in that game in which I want to create it, there are no values below 0, because pointX = 0 is on left screen border.
I want to create function which will smoothly count all values depends on our game resolution X.
For example:
parameters: min value, max value, screenX, cursorPosition
if(cursorPosition == screenWidth/2) then
return 0
end
When cursor position is below screenWidth/2, function will smoothly count value between -0 and min value (min value will be, when cursor position = 0)
and the same when cursor pos is above screenWidth/2, function will smoothly count value between 0 and max value (max value will be when cursor position = our screenX)
Can anyone explain to me, how can I reach an effect like that? :)
Regards
use linear interpolation to change the dynamic range. Let assume your view has xs,ys resolution and point (0,0) is top left corner. so the dynamic range per each axis is:
x = <0,xs-1>
y = <0,ys-1>
and you want to change it to:
x' = <minx,maxx>
y' = <miny,maxy>
So do this:
x' = minx + x*(maxx-minx)/(xs-1)
y' = miny + y*(maxy-miny)/(ys-1)
and if you need to go back for any reason:
x = (x'-minx)*(xs-1)/(maxx-minx)
y = (y'-miny)*(ys-1)/(maxy-miny)
where (minx,miny) is top left corner and (maxx,maxy) is bottom right corner. If you want to change also the sign of any axis then you can as minx<maxx is not required for this so just swap the initial values so minx>maxx.
Not coding in lua but If your values are floating then beware integer rounding while mixing integers and floats together.
I've got two rectangles represented by structures that contain the x1, y1, x2, y2 coordinates. One rectangle can be considered the parent, another the child.
I already know how to detect if the child rectangle is within the parent rectangle; what I'm trying to figure out now is the simplest, fastest way to determine the rectangular areas within the parent that are not being overlapped by the child rectangle.
For example, consider a 100x100 parent rectangle, and a 50x50 child rectangle located exactly in the center of the parent. This would mean there would be four rectangles representing the four areas in the parent rectangle that aren't being overlapped by the child.
Of course, the child could be in the top left, top right, bottom left, bottom right corner, or a little to the left, a little to the right, etc... there might be one, two, three, or four rectangles that represent the non-overlapped areas.
I've had some ideas for implementations to figure this out, but all seem overly complex. Is there a simple, fast way to figure this out?
So there could be up to 4 rectangles of non-overlapped area. Let's make a list of them.
leftrect = rightrect = toprect = bottomrect = None
trimmedparent = duplicate(parent)
if parent.x1 < child.x1:
leftrect = duplicate(parent)
leftrect.x2 = child.x1
trimmedparent.x1 = child.x1
if parent.x2 > child.x2:
rightrect = duplicate(parent)
rightrect.x1 = child.x2
trimmedparent.x2 = child.x2
if parent.y1 < child.y1:
toprect = duplicate(trimmedparent)
toprect.y2 = child.y1
if parent.y2 > child.y2:
bottomrect = duplicate(trimmedparent)
bottomrect.y1 = child.y2
The only tricky part is eliminating the part where e.g leftrect and toprect might intersect. I used 'trimmedparent' as an intermediate step to trim that section from toprect.
parent = Rectangle.new(x1,y1,mx1,my1)
child = Rectangle.new(x2,y2,mx2,my2)
rects = []
if (parent.contains(child))
rects.push Rectangle.new(parent.x, parent.y, parent.mx, child.y) if child.y>parent.y
rects.push Rectangle.new(parent.x, child.my, parent.mx, parent.my) if child.my<parent.my
rects.push Rectangle.new(parent.x, parent.y, child.x, pareny.my) if child.x>parent.x
rects.push Rectangle.new(child.mx, parent.y, parent.mx, parent.my) if child.mx<parent.mx
end
This is the basic algorithm:
For each point in the child, if it is inside the parent, the corresponding child and parent point form the diagonal a rectangle. Now, for each side of the child, if the two points are in the parent, those two points and the matching points on the edge of the parent form a rectangle. If only one of the points on the edge of the child is in the parent, this point and the parent point corresponding to the child edge point not in the parent form the diagonal for a rectangle. Return these rectangles.
You would get a maximum of eight rectangles (one for each corner, one for each edge). If you want the minimum possible rectangles, see if they share edges, and if they do, combine them.
Here's another way to calculate the non-overlapped area of the parent:
Function max(ByVal v1 As Double, ByVal v2 As Double) As Double
If v1 > v2 Then
Return v1
Else
Return v2
End If
End Function
Function min(ByVal v1 As Double, ByVal v2 As Double) As Double
If v1 > v2 Then
Return v2
Else
Return v1
End If
End Function
Function IntervalOverLap(ByVal p1 As Double, ByVal p2 As Double, ByVal c1 As Double, ByVal c2 As Double) As Double
'determine how much of the parent(p1 to p2) segment '
' is overlapped by the child(c1 to c2) segment '
'sort to standard direction '
Dim ph As Double = max(p1, p2)
Dim pl As Double = min(p1, p2)
Dim ch As Double = max(c1, c2)
Dim cl As Double = min(c1, c2)
'restrict the child to within the parent '
ch = min(ph, max(pl, ch))
cl = max(pl, min(cl, ph))
'return the overlapped length '
Return (ch - cl)
End Function
Function NonOverLappedArea(ByVal parent As Rectangle, ByVal child As Rectangle) As Double
'return the area of the parent '
' that is not overlapped by the child '
Return IntervalOverLap(parent.X1, parent.X2, child.X1, child.X2) _
* IntervalOverLap(parent.Y1, parent.Y2, child.Y1, child.Y2)
End Function
From your description, the child is always wholly contained by the parent. So the non-overlapping area is always going to be a rectangular donut, although it could be degenerate on any of the 4 sides since, a child edge could abut a parent edge, the fully degenerate case being the child is the same as the parent.
The donut can be decomposed into 4 rectangles. The decomposition may not be unique, meaning you could get different rectangles depending on how you perform the decomposition.
Of the 4 rectangles, discard the degenerate ones (those with 0 area) and you're done.
Here's a vertically biased decomposition
// assume the child is known to be in the parent bounds at this point
// assume parent and child are normalized
std::vector<CRect> rects;
CRect rect( parent.x1(), parent.y1(), child.x1(), parent.y2() ); // left
if ( rect.area() > 0.0 ) rects.push_back(rect);
rect.set( child.x1(), parent.y1(), child.x2(), child.y1() ); // bottom
if ( rect.area() > 0.0 ) rects.push_back(rect);
rect.set( child.x1(), child.y2(), child.x2(), parent.y2() ) ); // top
if ( rect.area() > 0.0 ) rects.push_back(rect);
rect.set( child.x2(), parent.y1(), parent.x2(), parent.y2() ) ); // right
if ( rect.area() > 0.0 ) rects.push_back(rect);
// yes, this could be written without all the code replication... :)