Drawing an arc with negative rectangle c# - c#

I'm trying to draw an arc of a circle in C#. The general code to do this is:
e.DrawArc(pen, x, y, d, d, startAngle, endAngle - startAngle);
Where x and y indicate the upper left corner of the Rectangle and d the width of the Rectangle (also the diameter of the arc).
The problem I'm facing is that sometimes I need to draw an arc whoose rectangle x and y values lie outside the bitmap I'm drawing onto (they may even be negative), and thus the arc is not being drawn at all.
Any ideas?
Thanks!

Okay, so I solved it using the Graphics.DrawCurve(pen, points[]) method. I calculated multiple points of the circle doing some math and plotted them as a curve. The result is pretty neat (around 20 points I can't tell that it's not an actual circle), and it works no matter where I want to draw the arc.

Related

User-Resizable and User-Rotatable shapes on Canvas with WPF

I'm currently creating a drawing software using WPF Shapes on canvas.
I've created a system allowing the user to move and rotate shapes on a Canvas using a transparent canvas upon the shape (which rotate with the shape) :
The green point is used to rotate the shape, the blue zone upon the rectangle is used to move the shape. I'd like to use my 4 red points to re-size the shape.
But the shape is rotatable, so corners coordinates aren't completely relevant to resize the shape. It seems, in my opinion, to be relevant only if the rotation is equals to 0, because the Left-Top Corner can be the Bottom-Right one after a 180 degree rotation.
Right now I'm using a RotateTransform to achieve the rotation with a 0.5, 0.5 RenderTransformOrigin. I'd like to avoid the use of a ScaleTransform because I want to keep the StrokeThickness at the size it is.
All red dots are pseudo-draggable (using MouseDown, MouseMove, MouseUp events). I use a buffer point which gives me the delta in X and Y between two mouse events.
How can use the deltas to resize the shape, even if it is rotated or moved ?
You can use the deltas to resize the shape if it is rotated. The only thing you have to do is rotating the mousemovement either. As you can see:
The movement of the mouse from origin to location describes a 2-D-vector. You can rotate this vector mathematically by using this formula:
x' = cos(theta) * x - sin(theta) * y
y' = sin(theta) * x + cos(theta) * y
where x/y is the current location of the mouse relative to the origin of the resize and theta the angle of rotation which can be found in the RotateTransform-object (Angle-Property) of the shape. At this point I don't know exactly if you have to use -theta, because the vector has to rotate in the opposite direction.
You can pick x'/y' for calculating the deltas and resize the shape like if it wasn't rotated.
I did not implement this myself. This is just a general idea. Maybe I can serve with a little code if you try this and give feedback or specify the problem more deeply or update your question with some code.
Appendix:
Resizing the shape using the deltas should be easy if you can access the width- and height-property of the shape. You simply add/subtract the x-delta to/from width and/or add/subtract the y-delta to/from height, depending on the grabbed point. This isn't affected by the location of the shape within the canvas.
Maybe you have to adjust the Canvas.Left/Canvas.Top-Property of the shape. I.e. if the user grabs the left upper point and resizes it to left/up, you should subtract the deltas from left and top porperty as well. Otherwise it will expand to right/down.

Maximize Rectangle in an Area on the X, Y plane with a list of points representing the area

Okay, I need help maximizing the area of a rectangle in the sliver object that can be many different shapes. I've already done most of the work.
I'm working in C# with a kinect and the depth pixels.
This image is just the best representation of what I'm talking about that I could find.
I need to produce a rectangle in this area on the x, y plane that maximizes the area while having every edge be solid.
I already have the solid shape represented as a list of points on the x, y plane. So I have the shape on the 2D plane. Kind of like this:
To simplify the problem, I'm just going to produce a rectangle with edges that are parallel to the x and y lines.
I'm not looking for code. I just need some direction or an algorithm that I can read up on and attempt to implement.
If any clarification is needed, please let me know.
If you just needs bounding rectangle you can traverse the list of points. Store minimum and maximum of X and Y (like minX, minY, maxX, maxY). Go through the whole list, and do a 4 if check on each of points like:
if(point.X < minX) minX = point.X
if(point.Y < minY) minY = point.Y
if(point.X > maxX) maxX = point.X
if(point.Y > maxY) maxY = point.Y
This will give you the bounding rectangle. Min and Max are two points that represent, depending on your coordinate system, upper left and lower right point, which you can easily use to draw the rectangle.
Have a look at the Largest Empty Rectangle problem. Here is one article with an algorithm to compute its solutions.
More precisely, it is a problem that consists in searching the largest area that does not contain any point given a set of points. In your case you can apply it to some points that would describe the edge of your 2D shape, plus some points on the outside. Then the procedure of the article would compute the largest rectangle in the yellow area. I did apply such a procedure to find the largest part of an image that does not contain transparent pixels. It worked well but was a bit slow.
The solution applies to a set of points (i.e. no segments) but you can easily compute an approximate solution with an approximation of your shape.

How to hide/not draw part of the model

I have an animated model that's spinning.
I want to hide/not draw any part of the model that's Y<0
what are the ways I can do it?
ideas:
1) draw a giant rectangular box right below y=0
2) tweak the camera matrix so that y<0 is outside of clipping plane (but i have no idea how)
can someone point me into the right direction? =)
A purely mathematical approach:
Don't draw the polygons whose y's are all less than 0.
Draw the polygons whose y's are all greater than or equal to 0.
Clip the rest of the polygons with the y=0 plane and draw them.
If the polygons making up the model are triangles, clipping them is pretty trivial. You need to clip the two sides intersecting with the y=0 plane and replace the original vertices whose y's are less than 0 with the intersection points of those two sides with the clipping plane.
Use the line equations:
(x-x1) = (x2-x1)*(y-y1)/(y2-y1)
(z-z1) = (z2-z1)*(y-y1)/(y2-y1)
where 1 and 2 are the vertices of the side being clipped by the y=0 plane. Substitute their coordinates (x1, y1, z1, x2, y2, z2) and y=0 into the equations to get x and z of the intersection point. Use this point's coordinates instead of vertex 1's or 2's (whichever has y < 0).
If the polygons are texture-mapped, you'll need to recalculate the texture coordinates for the vertices that you got from the clipping. You do that in the same fashion.
It sounds like you need to introduce MSDN Bounding Frustum
Here is a good tutorial from Nic's GameDev Site.

Create a rectangle to cover a rotated Microsoft.XNA.Framework.Rectangle

If I have a Rectangle class in C# how can I get a rectangle which encompasses it when it's rotated?
Basically I want to find the rectangle for a rotated rectangle.
I'm curious how do you keep your Rectangle as a data structure, I mean, a rectangle is 2D and XNA makes me think about 3D.
However, even in 2D and 3D, i think what you want is called AABB (axis aligned bounding box), which is very easy to find because it is defined by the two points formed by the minimums and, respective, maximums on each axis of each point of the original rectangle transformed with your rotation.
LATER EDIT:
For a Rectangle structure that contains X, Y, Width and Height, the rectangle has this two points:
(x1, y1) = (X, Y) and
(x2, y2) = (X + Width, Y + Width).
When you rotate the rectangle, you practically rotate this two points and obtain:
(xr1, yr1) = rotate(x1, y1)
(xr2, yr2) = rotate(x2, y2).
Now, the rectangle you want is defined by the points of these coordinates:
p1 = new Point(Min(xr1, xr2), Min(yr1, yr2))
p2 = new Point(Max(xr1, xr2), Max(yr1, yr2))
rotate is the method that rotates your rectangle by an angle around a certain point.
How are you rotating the rectangle to start with? to get the bounding box you need to look at the four resulting points and find the min and max for Y and X,

Draw Points onto canvas using an offset?

I have an array of Point variables. When drawn using Graphics.DrawLine, they create the expected image. My problem is that 0,0 is actually the center of the image (not the top left of my canvas as expected. My X and Y coordinates in the Points can contain negative numbers.
When I try to draw this to my Image, of course I get 1/4 of the total image as the remainder is drawn outside the bounds of my canvas. How do I center this drawing correctly onto my canvas?
I know the dimensions of the image I want to draw. I know where 0,0 is (width / 2, height / 2).
I suppose I can translate each and every single Point, but that seems like the hard way to do this.
TranslateTransform() can map coordinates for you if you setup a transformation during your drawing handlers.
Graphics.TranslateTransform # MSDN
Or, map your coordinates by adding half the width and half the height of the desired viewing area to each coordinate.
Also, you may need to scale your coordinates. You may use Graphics.ScaleTransform to do this.
Graphics.ScaleTransform # MSDN
If you don't wish to use this, then you should divide X coordinates by the percent amount you wish to stretch the width, and divide Y coordinates by the percent amount you wish to stretch the height. This gives us 1 for 100%, 1.2 for 120%, 0.8 for 80%, etc.
Welcome to the Windows' version of the Cartessian Plane. Your last statement is correct. You do have to offset each and every point. The only real help you can give yourself is to make the offset logic a separate method to clean up your main drawing code.
When creating the array, add an offset to each x value equal to half of the width and an offset to y equal to half of the height. That way when the points are drawn, they're in the expected position.

Categories