I've got question,
I have rounded rectangle. It's only rounded on right side, and straight on left. I want to make that in other way - left rounded, right straight.
What should I change?
int ArcWidth = 10 * 2;
int ArcHeight = 10 * 2;
int ArcX1 = Rect.Left;
int ArcX2 = Rect.Right -(ArcWidth + 1);
int ArcY1 = Rect.Top;
int ArcY2 = Rect.Bottom -(ArcHeight + 1);
path.AddArc(ArcX1, ArcY1, 1, 1, 180, 90); // Top Left
path.AddArc(ArcX2, ArcY1, ArcWidth, ArcHeight, 270, 90); //Top Right
path.AddArc(ArcX2, ArcY2, ArcWidth, ArcHeight, 360, 90); //Bottom Right
path.AddArc(ArcX1, ArcY2, 1, ArcHeight, 90, 90); //Bottom Left
Switch the sides that are rounded. Looks like you have all of your sides laid out. Switch all your numbers.
I found solution here:
http://tech.pro/tutorial/656/csharp-creating-rounded-rectangles-using-a-graphics-path
The way is to draw a Line, not Arc... (yes I know that was obvious)
Related
I'm trying to draw one ellipse at 0,0 and it's working but on the other side at pictureBox1.Width it's not drawing anything :
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillEllipse(Brushes.Purple, 0, 0, 5, 5);
e.Graphics.FillEllipse(Brushes.Purple, pictureBox1.Width, 0, 5, 5);
}
The result is one ellipse filled on the left side at 0,0 but on the right side nothing.
There should be small purple point also near the right yellow one.
And then to draw filled ellipse on all the 4 corners on the pictureBox1.
The result is one ellipse filled on the left side at 0,0 but on the right side nothing. There should be small purple point also near the right yellow one.
This is because it's off the screen a bit, you'll need to adjust the X coordinate.
e.Graphics.FillEllipse(Brushes.Purple, pictureBox1.Width - 5, 0, 5, 5);
If you'd like all four corners:
int circleSize = 5;
e.Graphics.FillEllipse(Brushes.Purple, 0, 0, circleSize, circleSize); //top left
e.Graphics.FillEllipse(Brushes.Purple, pictureBox1.Width - circleSize, 0, circleSize, circleSize); //top right
e.Graphics.FillEllipse(Brushes.Purple, pictureBox1.Width - circleSize, pictureBox1.Height - circleSize, circleSize, circleSize); //bottom right
e.Graphics.FillEllipse(Brushes.Purple, 0, pictureBox1.Height - circleSize, circleSize, circleSize); //bottom left
I have been looking for quite a while for an already pre-made function for creating a rounded rectangle that doesn't cause tearing/glitching like the one below. Credits to #György Kőszeg. This function works fine if the rectangle is big enough. When you start making the rectangle smaller you run into issues like the below image. I am looking for an easy fix for this.
If this issue is on this website and I have missed it, I do apologize for re-asking. (I remember asking this a while back either on here or on another website and receiving an answer that worked amazingly) This issue has been paining me for quite awhile (again).
public static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath();
if (radius == 0)
{
path.AddRectangle(bounds);
return path;
}
// top left arc
path.AddArc(arc, 180, 90);
// top right arc
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
// bottom right arc
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
// bottom left arc
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
UPDATE:
In the meantime I have started to use the code below which just overrides the rectangle if the width is less than the height. This creates a perfect circle (the smallest the rounded rectangle can be without the glitching/tearing). A comment was placed on this stating I should not use "tearing" because its simply caused by the math which I understand but I really have no idea what else to call the glitchy rectangle in the image.
Basically I want a oval instead of a circle to correctly reflex the "Exp" value.
public static GraphicsPath RoundedRect(Rectangle bounds, int radius)
{
int diameter = radius * 2;
Size size = new Size(diameter, diameter);
Rectangle arc = new Rectangle(bounds.Location, size);
GraphicsPath path = new GraphicsPath();
//new code here//
if(bounds.Height >= bounds.Width)
{
bounds.Width = bounds.Height;
}
if (radius >= diameter) {
path.AddRectangle(bounds);
return path;
}
// top left arc
path.AddArc(arc, 180, 90);
// top right arc
arc.X = bounds.Right - diameter;
path.AddArc(arc, 270, 90);
// bottom right arc
arc.Y = bounds.Bottom - diameter;
path.AddArc(arc, 0, 90);
// bottom left arc
arc.X = bounds.Left;
path.AddArc(arc, 90, 90);
path.CloseFigure();
return path;
}
Something like this may work better. Try it with various values for curveSize. Note that curveSize must be between 1 and the minimum of rect.Width/4 and rect.Height/4:
public static GraphicsPath RoundedRect(Rectangle rc, float curveSize)
{
if (curveSize < 0 || curveSize > rc.Height / 4.0f || curveSize > rc.Width / 4.0f)
curveSize = 0;
var result = new GraphicsPath();
if (curveSize > 0)
{
float size4 = curveSize * 4;
result.AddArc(rc.Right - size4, rc.Top, size4, size4, 270, 90);
result.AddArc(rc.Right - size4, rc.Bottom - size4, size4, size4, 0, 90);
result.AddArc(rc.Left, rc.Bottom - size4, size4, size4, 90, 90);
result.AddArc(rc.Left, rc.Top, size4, size4, 180, 90);
result.CloseFigure();
}
else if (rc.Width > 0 && rc.Height > 0)
{
result.AddRectangle(rc);
}
return result;
}
I have a rectangular selection made programatically on an Image.The user is provided the option to set the size of the rectangle,on doing so the rectangle size should increase but the center point of the old rectangle should be maintained,so that the contents within the rectangle is not out of focus.
Is this a correct approach
objSmall.X = CInt(objBig.X + (Math.Round(((objBig.Width / 2) - (objSmall.Width / 2)), 0)))
objSmall.Y = CInt(objBig.Y + (Math.Round(((objBig.Height / 2) - (objSmall.Height / 2)), 0)))
The new rectangle can be larger or smaller than the old one.
The calculation is correct; it can be simplified using just one integer division:
(and translated to C#, because the source code is VB.Net)
An integer division (MSDN Docs) can be used because we're dividing by 2, it's like rounding down. But you should use floating point values (float) when drawing, especially moving objects (with values expressed in both degrees and, of course, radians): your positions will be off quite a bit if you don't.
objSmall.X = objBig.X + (objBig.Width - objSmall.Width) / 2;
objSmall.Y = objBig.Y + (objBig.Height - objSmall.Height) / 2;
Or (2):
objSmall.Location = new Point(objBig.X + (objBig.Width - objSmall.Width) / 2,
objBig.Y + (objBig.Height - objSmall.Height) / 2);
Or, using the relative Centre coordinates of the larger object:
Point BigRectCenter = new Point((objBig.Width / 2) + objBig.X, (objBig.Height / 2) + objBig.Y);
objSmall.Location = new Point(BigRectCenter.X - (objSmall.Width / 2),
BigRectCenter.Y - (objSmall.Height / 2));
The (2) method can be also used when you don't know which one of the Rectangles is the largest.
Assume you know your reference Rectangle's Location and Size and you let the User specify the new Size of the selection:
Rectangle OriginalRect = new Rectangle(30, 30, 120, 90);
Rectangle ResizedRect = new Rectangle(0, 0, 140, 140);
The ResizedRect has a Size (defined by the User) but its Location is unknown at this point.
The new selection Rectangle's (ResizedRect) Location can be calculated with:
ResizedRect.Location = new Point(OriginalRect.X + (OriginalRect.Width - ResizedRect.Width) / 2,
OriginalRect.Y + (OriginalRect.Height - ResizedRect.Height) / 2);
Original Selection (Green) Original Selection (Green)
(20, 20, 120, 120) (30, 30, 120, 90)
Resized Selection (Red) Resized Selection (Red)
( 0, 0, 95, 86) ( 0, 0, 140, 140)
Calculated Selection Calculated Selection
Rectangle Rectangle
(32, 37, 95, 86) (20, 5, 140, 140)
I have a line drawn from two rectangles, spanning from xpos, ypos to xpos2, ypos2. I'm trying to detect if a rectangle (stored in 4 arrays of X/Y pos and random speed in those two directions) collides with the line.
I've tried (Vector2.Distance(new Vector2(xpos + 13, ypos + 13), new Vector2(EnX[index], EnY[index])) + Vector2.Distance(new Vector2(xpos2 + 13, ypos2 + 13), new Vector2(EnX[index], EnY[index])) == Vector2.Distance(new Vector2(xpos + 13, ypos + 13), new Vector2(xpos2 + 13, ypos2 + 13))) in a if statement, but that doesn't work.
EDIT: I've now tried
m = (ypos2 + 13 - ypos + 13) / (xpos2 + 13 - xpos + 13);
b = ((m * xpos2 + 13) - ypos2 + 13);
if (EnY[index] == m * EnX[index] + b)
Where Xpos/2 and ypos/2 are the line starting points. EnX[] and EnY[] are the "enemy" X and Y positions, where I'm trying to check if they're hitting a line.
I assume that you have the rectangle's corner positions as 2d vectors:
Vector2[] corners;
The rectangle intersects with the line if any two corner points lie on the opposite side of the line. To evaluate the side, we need the line's normal (the slope approach you tried may fail for vertical lines):
Vector2 normal = new Vector2D(ypos2 - ypos, xpos - xpos2);
We can then use the sign of the dot product to evaluate the side:
Vector2 lineStart = new Vector2(xpos, ypos);
//we don't know yet on which side of the line the rectangle lies
float rectangleSide = 0;
foreach(Vector2 corner in corners)
{
//cornerSide will be positive if the corner is on the side the normal points to,
//zero if the corner is exactly on the line, and negative otherwise
float cornerSide = Vector2.Dot(corner - lineStart, normal);
if(rectangleSide == 0)
//first evaluated corner or all previous corners lie exactly on the line
rectangleSide = cornerSide;
else
if(cornerSide != 0 && //ignore corners on the line
(cornerSide > 0) != (rectangleSide > 0)) //different sides
return true; //rectangle intersects with line
}
return false; //rectangle does not intersect with line
How can I draw a horizontal box at the bottom of my viewport in OpenGL? This is drawing it at the top. What's wrong?
var H = window height;
var len = 20;
gl.Vertex3d(0, H - len, 0); //top left
gl.Vertex3d(Width, H - len, 0); //top right
gl.Vertex3d(Width, H + len, 0); //bottom left
gl.Vertex3d(0, H + len, 0); //bottom right
OpenGL's default coordinate space has Y pointing upward. You can change that, or you can change your vertices, depending on what you're going to do and what you're used to. In the case you've posted, where it's just a single quad, you can probably just change the vertices and do something like this:
gl.Vertex3d(0, len, 0); //top left
gl.Vertex3d(Width, len, 0); //top right
gl.Vertex3d(Width, -len, 0); //bottom left
gl.Vertex3d(0, -len, 0); //bottom right
If you're drawing a lot of other stuff, you can set the current transform matrix as you need to before drawing (and possibly restore it afterwards), by doing something along the lines of:
gl.matrixMode(GL_PROJECTION);
gl.ortho(left, right, top, bottom, near, far); // Note reversal of top and bottom