ZedGraph PointPairs only 1 symbol - zedgraph

I'm hoping someone may have the answer to this one
I've added some "PointPair" values to a ZedGraph graph, and this all works fine. However, when I show Symbols, it only shows the symbol on the high value, not the low value.
Does anyone know what could be causing this?
EDIT - Code Sample (sorry, I should've put this on yesterday)
// GraphPane pane (field)
FilledLineItem filledLineItem = new FilledLineItem("myline", upperPoints, lowerPoints, Color.DodgerBlue, ZedGraph.SymbolType.Square)
pane.CurveList.Add(filledLineItem);
Where upperPoints and lowerPoints are of type PointPairList

I have discovered the problem in the ZedGraph library...someone please correct me if I've missed something I shouldn't have
When using a FilledLineItem, this has a set of upper points and lower points.
When "Draw" is called, it is called on the LineItem class - which only has a set of points.
So I have added to the Draw method:
DrawPoints(pane, maxX, maxY, curve, curve.LowerPoints, g, source, scaleFactor, minX, minY, isPixelDrawn)
DrawPoints is a method that I extracted out of the "Draw" method in "Symbol". It contains the following
private void DrawPoints(GraphPane pane, int maxX, int maxY, LineItem curve, IPointList points, Graphics g, Symbol source, float scaleFactor, int minX, int minY, bool[,] isPixelDrawn)
{
double curX;
double curY;
int tmpX;
int tmpY;
double lowVal;
if ( points != null && ( _border.IsVisible || _fill.IsVisible ) )
{
SmoothingMode sModeSave = g.SmoothingMode;
if ( _isAntiAlias )
g.SmoothingMode = SmoothingMode.HighQuality;
// For the sake of speed, go ahead and create a solid brush and a pen
// If it's a gradient fill, it will be created on the fly for each symbol
//SolidBrush brush = new SolidBrush( this.fill.Color );
using ( Pen pen = source._border.GetPen( pane, scaleFactor ) )
using ( GraphicsPath path = MakePath( g, scaleFactor ) )
{
RectangleF rect = path.GetBounds();
using ( Brush brush = source.Fill.MakeBrush( rect ) )
{
ValueHandler valueHandler = new ValueHandler( pane, false );
Scale xScale = curve.GetXAxis( pane ).Scale;
Scale yScale = curve.GetYAxis( pane ).Scale;
bool xIsLog = xScale.IsLog;
bool yIsLog = yScale.IsLog;
bool xIsOrdinal = xScale.IsAnyOrdinal;
double xMin = xScale.Min;
double xMax = xScale.Max;
// Loop over each defined point
for ( int i = 0; i < points.Count; i++ )
{
// Check that this symbol should be shown, if not, then continue to the next symbol
if(!points[i].ShowSymbol)
{
continue;
}
// Get the user scale values for the current point
// use the valueHandler only for stacked types
if ( pane.LineType == LineType.Stack )
{
valueHandler.GetValues( curve, i, out curX, out lowVal, out curY );
}
// otherwise, just access the values directly. Avoiding the valueHandler for
// non-stacked types is an optimization to minimize overhead in case there are
// a large number of points.
else
{
curX = points[i].X;
if ( curve is StickItem )
curY = points[i].Z;
else
curY = points[i].Y;
}
// Any value set to double max is invalid and should be skipped
// This is used for calculated values that are out of range, divide
// by zero, etc.
// Also, any value <= zero on a log scale is invalid
if ( curX != PointPair.Missing &&
curY != PointPair.Missing &&
!System.Double.IsNaN( curX ) &&
!System.Double.IsNaN( curY ) &&
!System.Double.IsInfinity( curX ) &&
!System.Double.IsInfinity( curY ) &&
( curX > 0 || !xIsLog ) &&
( !yIsLog || curY > 0.0 ) &&
( xIsOrdinal || ( curX >= xMin && curX <= xMax ) ) )
{
// Transform the user scale values to pixel locations
tmpX = (int) xScale.Transform( curve.IsOverrideOrdinal, i, curX );
tmpY = (int) yScale.Transform( curve.IsOverrideOrdinal, i, curY );
// Maintain an array of "used" pixel locations to avoid duplicate drawing operations
if ( tmpX >= minX && tmpX <= maxX && tmpY >= minY && tmpY <= maxY ) // guard against the zoom-in case
{
if ( isPixelDrawn[tmpX, tmpY] )
continue;
isPixelDrawn[tmpX, tmpY] = true;
}
// If the fill type for this symbol is a Gradient by value type,
// the make a brush corresponding to the appropriate current value
if ( _fill.IsGradientValueType || _border._gradientFill.IsGradientValueType )
{
using ( Brush tBrush = _fill.MakeBrush( rect, points[i] ) )
using ( Pen tPen = _border.GetPen( pane, scaleFactor, points[i] ) )
this.DrawSymbol( g, tmpX, tmpY, path, tPen, tBrush );
}
else
{
// Otherwise, the brush is already defined
// Draw the symbol at the specified pixel location
this.DrawSymbol( g, tmpX, tmpY, path, pen, brush );
}
}
}
}
}
g.SmoothingMode = sModeSave;
}
}
So my "Draw" method now looks like this:
public void Draw( Graphics g, GraphPane pane, LineItem curve, float scaleFactor,
bool isSelected )
{
Symbol source = this;
if ( isSelected )
source = Selection.Symbol;
int tmpX, tmpY;
int minX = (int)pane.Chart.Rect.Left;
int maxX = (int)pane.Chart.Rect.Right;
int minY = (int)pane.Chart.Rect.Top;
int maxY = (int)pane.Chart.Rect.Bottom;
// (Dale-a-b) we'll set an element to true when it has been drawn
bool[,] isPixelDrawn = new bool[maxX + 1, maxY + 1];
double curX, curY, lowVal;
DrawPoints(pane, maxX, maxY, curve, curve.Points, g, source, scaleFactor, minX, minY, isPixelDrawn);
// Need to check if this is a "Filled" line item, if it is, it may have lower points, in which case the lower points need to be output as well
FilledLineItem filledLineItem = curve as FilledLineItem;
if (filledLineItem != null)
{
DrawPoints(pane, maxX, maxY, curve, filledLineItem.LowerPoints, g, source, scaleFactor, minX, minY, isPixelDrawn);
}
}
...after casting the curve to a FilledLineItem (but not before checking that it is actually a FilledLineItem).
This has fixed the problem, and I hope it helps anyone else who may have the same problem.

Related

iText merge, scale and rotate pages in existing pdf

I want to concat existing pdf and also scale and rotate them to A4 portrait pages. Today i have done this with pdfWriter:
for (int pageNum = 1; pageNum <= numberOfPages; pageNum++) {
PdfImportedPage importedPage = writer.getImportedPage( reader, pageNum );
AffineTransform transform = getAffineTransform(reader, writer, pageNum);
pdfContentByte.addTemplate(importedPage, transform);
document.newPage();
}
private AffineTransform getAffineTransform(PdfReader reader, PdfWriter writer, int pageNum) {
Rectangle readerPageSize = reader.getPageSize( pageNum );
Rectangle writerPageSize = writer.getPageSize();
float rPageHeight = readerPageSize.getHeight();
float rPageWidth = readerPageSize.getWidth();
float wPageHeight = writerPageSize.getHeight();
float wPageWidth = writerPageSize.getWidth();
int pageRotation = reader.getPageRotation( pageNum );
boolean rotate = (rPageWidth > rPageHeight) && (pageRotation == 0 || pageRotation == 180);
if(!rotate)
rotate = ((rPageHeight > rPageWidth) && (pageRotation == 90 || pageRotation ==270));
//if changing rotation gives us better space rotate an extra 90 degrees.
if(rotate) pageRotation += 90;
double randrotate = (double)pageRotation * Math.PI/(double)180;
AffineTransform transform = new AffineTransform();
float margin = 0;
float scale = 1.0f;
if(pageRotation == 90 || pageRotation == 270 ){
scale = Math.min((wPageHeight - 2 * margin) / rPageWidth, (wPageWidth- 2 * margin) / rPageHeight);
} else {
scale = Math.min(wPageHeight / rPageHeight, wPageWidth / rPageWidth);
}
transform.translate((wPageWidth/2) + margin, wPageHeight/2 + margin);
transform.rotate(-randrotate);
transform.scale(scale,scale);
transform.translate(-rPageWidth/2,-rPageHeight/2);
return transform;
}
This works fine, but removes layers (OCG) and annotations.
Is it possible to get this to work with layers (OCG) and annotations? This is used for print, so I only need the pdf to display the same, I don't actually need the layers or annotations.

'Grenade' projection based on angle + bounce

I'm having some trouble with synthesizing an advanced object projection formula. I have already figured out few basic physic simulation formulas such as:
Velocity of object:
x += cos(angle);
y += sin(angle);
*where angle can be obtained by either mouse position or with tan(...target and intial values)
but that only travels straight based on the angle.
Gravity:
Yvelocity = Yvelocity - gravity;
if(!isHitPlatform) {
Obj.y += YVelocity
}
Bounce:// No point if we've not been sized...
if (height > 0) {
// Are we bouncing...
if (bounce) {
// Add the vDelta to the yPos
// vDelta may be postive or negative, allowing
// for both up and down movement...
yPos += vDelta;
// Add the gravity to the vDelta, this will slow down
// the upward movement and speed up the downward movement...
// You may wish to place a max speed to this
vDelta += gDelta;
// If the sprite is not on the ground...
if (yPos + SPRITE_HEIGHT >= height) {
// Seat the sprite on the ground
yPos = height - SPRITE_HEIGHT;
// If the re-bound delta is 0 or more then we've stopped
// bouncing...
if (rbDelta >= 0) {
// Stop bouncing...
bounce = false;
} else {
// Add the re-bound degregation delta to the re-bound delta
rbDelta += rbDegDelta;
// Set the vDelta...
vDelta = rbDelta;
}
}
}
}
I need help way to combine these three formulas to create an efficient and lightweight algorithm that allows an object to be projected in an arch determined by the angle, yet continues to bounce a few times before coming to a stop, all with an acceptable amount of discontinuity between each point. *Note: Having the grenade be determined by a f(x) = -x^2 formula creates a larger jump discontinuity as the slope increases, forcing you to reverse the formula to find x = +-y value (to determine whether + or -, check the bounds).
something like:
class granade
{
private static final double dt = 0.1; // or similar
private double speedx;
private double speedy;
private double positionx;
private double positiony;
public granade(double v, double angle)
{
speedx = v * Math.cos(angle);
speedy = v * Math.sin(angle);
positionx = 0;
positiony = 0;
}
public void nextframe()
{
// update speed: v += a*dt
speedy -= gravity* dt;
// update position: pos += v*dt
positionx += speedx * dt;
double newpositiony = positiony + speedy*dt;
// bounce if hit ground
if (newpositiony > 0)
positiony = newpositiony;
else {
// bounce vertically
speedy *= -1;
positiony = -newpositiony;
}
}
public void draw() { /* TODO */ }
}
OT: avoid Math.atan(y/x), use Math.atan2(y, x)

How to find the Joint coordinates(X,Y,Z) ,also how to draw a locus of the tracked joint?

I am trying to develop a logic to recognize a circle which is made by users right hand, I got the code to draw the skeleton and track from the sample code,
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
}
}
using (DrawingContext dc = this.drawingGroup.Open())
{
// Draw a transparent background to set the render size
dc.DrawRectangle(Brushes.Black, null, new Rect(0.0, 0.0, RenderWidth, RenderHeight));
if (skeletons.Length != 0)
{
foreach (Skeleton skel in skeletons)
{
RenderClippedEdges(skel, dc);
if (skel.TrackingState == SkeletonTrackingState.Tracked)
{
this.DrawBonesAndJoints(skel, dc);
}
else if (skel.TrackingState == SkeletonTrackingState.PositionOnly)
{
dc.DrawEllipse(
this.centerPointBrush,
null,
this.SkeletonPointToScreen(skel.Position),
BodyCenterThickness,
BodyCenterThickness);
}
}
}
// prevent drawing outside of our render area
this.drawingGroup.ClipGeometry = new RectangleGeometry(new Rect(0.0, 0.0, RenderWidth, RenderHeight));
}
}
What I want to do now is to track the coordinates of users right hand for gesture recognition,
Here is how I am planning to get the job done:
Start the gesture
Draw the circled gesture, Make sure to store the coordinates for start and then keep noting the coordinates for every 45 degree shift of the Joint from the start, for 8 octants we will get 8 samples.
For making a decision that a circle was drawn we can just check the relation ship between the eight samples.
Also, in the depthimage I want to show the locus of the drawn gesture, so as the handpoint moves it leaves a trace behind so at the end we will get a figure which was drawn by an user. I have no idea how to achieve this.
Coordinates for each joint are available for each tracked skeleton during each SkeletonFrameReady event. Inside your foreach loop...
foreach (Skeleton skeleton in skeletons) {
// get the joint
Joint rightHand = skeleton.Joints[JointType.HandRight];
// get the individual points of the right hand
double rightX = rightHand.Position.X;
double rightY = rightHand.Position.Y;
double rightZ = rightHand.Position.Z;
}
You can look at the JointType enum to pull out any of the joints and work with the individual coordinates.
To draw your gesture trail you can use the DrawContext you have in your example or use another way to draw a Path onto the visual layer. With your x/y/z values, you would need to scale them to the window coordinates. The "Coding4Fun" library offers a pre-built function to do it; alternatively you can write your own, for example:
private static double ScaleY(Joint joint)
{
double y = ((SystemParameters.PrimaryScreenHeight / 0.4) * -joint.Position.Y) + (SystemParameters.PrimaryScreenHeight / 2);
return y;
}
private static void ScaleXY(Joint shoulderCenter, bool rightHand, Joint joint, out int scaledX, out int scaledY)
{
double screenWidth = SystemParameters.PrimaryScreenWidth;
double x = 0;
double y = ScaleY(joint);
// if rightHand then place shouldCenter on left of screen
// else place shouldCenter on right of screen
if (rightHand)
{
x = (joint.Position.X - shoulderCenter.Position.X) * screenWidth * 2;
}
else
{
x = screenWidth - ((shoulderCenter.Position.X - joint.Position.X) * (screenWidth * 2));
}
if (x < 0)
{
x = 0;
}
else if (x > screenWidth - 5)
{
x = screenWidth - 5;
}
if (y < 0)
{
y = 0;
}
scaledX = (int)x;
scaledY = (int)y;
}

Generating non-overlapping rectangle test sets

Alas this is a university type question, but one im struggling with none the less.
I need to generate large test sets of rectangles, non-overlapping, that can then be used to test an algorithm that finds the adjacencies between them. The test sets will need to probably have upwards of 10000 - 100000 rectangles in them. Ive been searching the net for examples of how to generate test sets like this, but have come up with nothing. Im aware that I could use a purely brute force method, and every time a random rectangle is generated, check whether or not it overlaps with any of the other rectangles, but this seems like generating the test sets will end up taking days if not longer!
Any one know how to go about doing this, or at least where I should start looking?
I found your idea fun and challanging and therefore tried a solution by using a matrix.
Basicly, the idea is (when talking in pixels) to create a matrix of booleans of the same width and height as the square root of MaxWidthOfRectangle * (NumberOfRectangles) (just for simplicity the same width and height).
Next, for each entry in the matrix, generate a random rectangle between min and max bounds. and set all the bools in the matrix for the specific rectangle. Now when generating the next rectangle, you can simply check "around" the desired location to determine how much space you can occupy rather then having to estimate a size and compare with each other rectangle if it conflicts.
My code:
class RectangleGenerator
{
readonly bool[,] _matrix;
readonly int _size;
readonly int _minimalBoxSize;
readonly int _maximumBoxSize;
readonly Random _random = new Random(1);
readonly List<Point> _offsets;
public bool[,] Matrix { get { return _matrix; } }
public RectangleGenerator(int size, int minimalBoxSize, int maximumBoxSize)
{
_matrix = new bool[size, size];
_size = size;
_minimalBoxSize = minimalBoxSize;
_maximumBoxSize = maximumBoxSize;
_offsets = new List<Point>(size * size);
Reset();
}
public IEnumerable<Rectangle> Calculate()
{
while (_offsets.Count > 0)
{
Point currentPoint = _offsets[_offsets.Count - 1];
_offsets.RemoveAt(_offsets.Count - 1);
if (!_matrix[currentPoint.X, currentPoint.Y])
{
Rectangle rectangle;
if (TryCreateNextRectangle(currentPoint.X, currentPoint.Y, out rectangle))
{
// fill the matrix with the rectangle + padding
int startFillX = Math.Max(0, rectangle.Left);
int startFillY = Math.Max(0, rectangle.Top);
int endFillX = Math.Min(_size, rectangle.Right);
int endFillY = Math.Min(_size, rectangle.Bottom);
for (int fillX = startFillX; fillX < endFillX; fillX++)
for (int fillY = startFillY; fillY < endFillY; fillY++)
{
_matrix[fillX, fillY] = true;
}
yield return rectangle;
}
}
}
}
private bool TryCreateNextRectangle(int x, int y, out Rectangle rectangle)
{
int maxWidth = DetermineMaxWidth(x, y, _minimalBoxSize);
int maxHeight = DetermineMaxHeight(y, x, maxWidth);
if (maxWidth < _minimalBoxSize || maxHeight < _minimalBoxSize)
{
rectangle = Rectangle.Empty;
return false;
}
int width = _random.Next(_minimalBoxSize, maxWidth);
int height = _random.Next(_minimalBoxSize, maxHeight);
rectangle = new Rectangle(x, y, width, height);
return true;
}
private int DetermineMaxWidth(int x, int y, int height)
{
int result = Math.Min(_maximumBoxSize, _size - x);
for (int offsetX = 0; offsetX < result; offsetX++)
for (int offsetY = 0; offsetY < height; offsetY++)
{
if (_matrix[x + offsetX, y + offsetY])
{
result = offsetX;
break;
}
}
return result;
}
private int DetermineMaxHeight(int y, int x, int width)
{
int result = Math.Min(_maximumBoxSize, _size - y);
for (int offsetY = 0; offsetY < result; offsetY++)
for (int offsetX = 0; offsetX < width; offsetX++ )
{
if (_matrix[x + offsetX, y + offsetY])
{
result = offsetY;
break;
}
}
return result;
}
public void Reset()
{
// append for padding:
for (int x = 0; x < _size; x++)
for (int y = 0; y < _size; y++)
{
_matrix[x, y] = false;
if (_size - x >= _minimalBoxSize && _size - y >= _minimalBoxSize)
{
_offsets.Add(new Point(x, y));
}
}
_offsets.Sort((x, y) => x == y ? 0 : _random.Next(-1, 1));
}
}

MonoDevelop.Components.Docking - Tabbed DockGroupType issue

Our application uses the MonoDevelop.Components.Docking framework in our
Windows application. We last updated to the latest version in November
2010. I have come across some interesting behavior that occurs in the
following situation:
Press the auto hide button of the first panel in a
DockGroupType.Tabbed ParentGroup
Hold mouse over collapsed panel until it expands
Drag panel into center of the tabbed group (back to original
spot) and drop
At this point the panel resizes to the size of the blue rectangle that
showed where the panel would be dropped, and then undocks from the main
window to float at that size. This only happens on the first item in a
tabbed group. I found a commented out section of code in
DockGroupItem.cs (line 112, GetDockTarget(..)) that seems as though it
might deal with this. However, it references a DockPosition type that is
not defined, CenterAfter. The method is below, with the commented out
portion in bold:
public bool GetDockTarget (DockItem item, int px, int py, Gdk.Rectangle rect, out DockDelegate dockDelegate, out Gdk.Rectangle outrect)
{
dockDelegate = null;
if (item != this.item && this.item.Visible && rect.Contains (px,py)) {
int xdockMargin = (int) ((double)rect.Width * (1.0 - DockFrame.ItemDockCenterArea)) / 2;
int ydockMargin = (int) ((double)rect.Height * (1.0 - DockFrame.ItemDockCenterArea)) / 2;
DockPosition pos;
/* if (ParentGroup.Type == DockGroupType.Tabbed) {
rect = new Gdk.Rectangle (rect.X + xdockMargin, rect.Y + ydockMargin,rect.Width - xdockMargin*2, rect.Height - ydockMargin*2);
pos = DockPosition.CenterAfter;
}
*/ if (px <= rect.X + xdockMargin && ParentGroup.Type != DockGroupType.Horizontal) {
outrect = new Gdk.Rectangle (rect.X, rect.Y, xdockMargin, rect.Height);
pos = DockPosition.Left;
}
else if (px >= rect.Right - xdockMargin && ParentGroup.Type != DockGroupType.Horizontal) {
outrect = new Gdk.Rectangle (rect.Right - xdockMargin, rect.Y, xdockMargin, rect.Height);
pos = DockPosition.Right;
}
else if (py <= rect.Y + ydockMargin && ParentGroup.Type != DockGroupType.Vertical) {
outrect = new Gdk.Rectangle (rect.X, rect.Y, rect.Width, ydockMargin);
pos = DockPosition.Top;
}
else if (py >= rect.Bottom - ydockMargin && ParentGroup.Type != DockGroupType.Vertical) {
outrect = new Gdk.Rectangle (rect.X, rect.Bottom - ydockMargin, rect.Width, ydockMargin);
pos = DockPosition.Bottom;
}
else {
outrect = new Gdk.Rectangle (rect.X + xdockMargin, rect.Y + ydockMargin, rect.Width - xdockMargin*2, rect.Height - ydockMargin*2);
pos = DockPosition.Center;
}
dockDelegate = delegate (DockItem dit) {
DockGroupItem it = ParentGroup.AddObject (dit, pos, Id);
it.SetVisible (true);
ParentGroup.FocusItem (it);
};
return true;
}
outrect = Gdk.Rectangle.Zero;
return false;
}
I have tried a few small things, but nothing as affected the behavior so
far. Any ideas on what I could edit to get this working properly?
Thanks!
To fix the problem above I added a check to see if the item being docked is the same as the first item in the tab group, if so, modifies the insertion index appropriately because trying to insert the item before itself in the group causes the float problem. Since its status was "AutoHide" it is still technically visible, so was kept in the tab group's list of visible objects. Changes are below.
DockGroup.cs (line 122) - commented out the index increase:
public DockGroupItem AddObject (DockItem obj, DockPosition pos, string relItemId)
{
...
else if (pos == DockPosition.CenterBefore || pos == DockPosition.Center) {
if (type != DockGroupType.Tabbed)
gitem = Split (DockGroupType.Tabbed, pos == DockPosition.CenterBefore, obj, npos);
else {
//if (pos == DockPosition.Center) // removed to fix issue with drag/docking the 1st tab item after autohiding
//npos++;
gitem = new DockGroupItem (Frame, obj);
dockObjects.Insert (npos, gitem);
gitem.ParentGroup = this;
}
}
ResetVisibleGroups ();
return gitem;
}
DockGroup.cs (line 912) - added check for same item
internal override bool GetDockTarget (DockItem item, int px, int py, out DockDelegate dockDelegate, out Gdk.Rectangle rect)
{
if (!Allocation.Contains (px, py) || VisibleObjects.Count == 0) {
dockDelegate = null;
rect = Gdk.Rectangle.Zero;
return false;
}
if (type == DockGroupType.Tabbed) {
// this is a fix for issue with drag/docking the 1st tab item after autohiding it
int pos = 0;
if (item.Id == ((DockGroupItem)VisibleObjects[0]).Id)
{
pos++;
}
// Tabs can only contain DockGroupItems
return ((DockGroupItem)VisibleObjects[pos]).GetDockTarget (item, px, py, Allocation, out dockDelegate, out rect);
}
...