Drawing Arcs in Pyside - python

I'm trying to do draw widgets on the circle, for this I need to paint the widgets as a arc. I know the number of widgets (let's say), then each widget is at 36 degrees from the origin to the circumference. The information I have is the center of circle, radius and I know the starting and end point on the circumference for each such widget.
This is computed by doing
dx = int(round(400 + 300 * np.cos(angle)))
dy = int(round(400 + 300 * np.sin(angle)))
where angle = 2 * np.pi / 15
I go over a for loop computing the new value for angle which is basically angle * i where i = (1, 10)
I don't understand the start angle and span angle for the arcs function in QPainter.QPainter Arc. I googled and not many terms came up. Maybe there is a different term for them.
So the problem is I have a starting point and ending point on the circumference and center and radius, how do I use them to draw Arcs such that I get something that looks like :
circos
What I have tried is, I can compute the center point (cx) of the two end points, if I draw a line from the center of the circle to this point cx, then I can compute how far this point circumference which essentially is my width, but how to get the orientation correct to represent them as circles.
Instead of circular I do have a layout with just lines like this, but would like to be like the circos one.
My image

I don't understand the start angle and span angle for the arcs function in QPainter.QPainter Arc.
Why? The documentation is IMHO very clear:
The startAngle and spanAngle must be specified in 1/16th of a degree, i.e. a full circle equals 5760 (16 * 360).
This means that your units are 1/16º. E.g. 45º is 45*16 units.
Positive values for the angles mean counter-clockwise while negative values mean the clockwise direction. Zero degrees is at the 3 o’clock position."
This means that 90*16 points at 12 o'clock (goes 90º counter-clockwise from 3 o'clock), and -90*16 points at 6 o'clock.
Of course the "zero" degrees only has sense for the start angle. The span angle states how much further does the arc go, and in which direction.
For example, to draw an arc from 3 o'clock to 12 o'clock, you'd do
painter.drawArc(rect, 0, 90*16)
*or*
painter.drawArc(rect, 90*16, -90*16)
But to draw an arc from 3 o'clock to 6 o'clock, you'd do
painter.drawArc(rect, 0, -90*16)
*or*
painter.drawArc(rect, -90*16, 90*16)
The arcs are not specified using center and radius, but rather using a bounding rectangle. If the arc was a full ellipse, it would be inscribed in the rectangle - the arcs are implicitly elliptical arcs.
So, given x and y centerpoint, and r for circular radius, the bounding rectangle is
rect = QRect(x-r, y-r, 2*r, 2*r)

Related

getting angle with known coordinates

I have an object on my canvas and I want to make an arrow pointing on it. I already have an image of arrow, that is pointing up, and I need to know the angle I must rotate it by to make it point on that image. The arrow is always at position (0, 0), but the position of the second picture can change.
I know I can count sine and cosine of that angle, but it's not the thing I'm looking for, It must be exactly that angle.
The angle is 90 - arctan(Y/X). You probably want to use math.atan2(y,x), and remember that returns radians, not degrees. If you want degrees, it's
angle = 90 - math.atan2(y,x) * 180 / math.pi

what does extent mean for the function circle?

from turtle import Turtle,Screen
t=Turtle()
s=Screen()
t.left(20)
from cmath import pi
print(pi)
circle=2*pi*40
print("circle=",circle)
t.circle(radius=50,extent=2*pi*50)
turtle docs says that
turtle.circle(radius, extent=None, steps=None)
Draw a circle with given radius. The center is radius units left of the turtle; extent – an angle – determines which part of the circle is drawn. If extent is not given, draw the entire circle. If extent is not a full circle, one endpoint of the arc is the current pen position. Draw the arc in counterclockwise direction if radius is positive, otherwise in clockwise direction. Finally the direction of the turtle is changed by the amount of extent.
As the circle is approximated by an inscribed regular polygon, steps
determines the number of steps to use. If not given, it will be
calculated automatically. May be used to draw regular polygons.

Draw precise circle through two points

I am programming an application for high precision measurements. Now I have a problem.
User can select a segment on axis X that would represent diameter of a circle.
How do I draw the circle in question through two selected end points if the selected diameter has even pixel length
In this case origin of the circle would be between two pixels, which would make me choose one of them, thus shifting the circle one pixel left or right.
It is true, the look wouldn't change because one pixel will be included and another added on the other side of selected segment, but what if I need to draw a square based on the segment's length around the area first.
Then circle and square would touch in wrong places.
What is usually done in this circumstances?
ImageDraw.Draw.ellipse takes a bounding box as a parameter. It doesn't care where the center of the circle goes.
The circle outline includes all 4 edges of the bounding box in the tests I performed. I suggest you do your own tests too.
Calculating the bounding box from two arbitrary points is easy, once you have the diameter and center of the circle.
diameter = ((x2 - x1)**2 + (y2 - y1)**2) ** 0.5
radius = diameter / 2
xC, yC = (x1 + x2) / 2.0, (y1 + y2) / 2.0
bbox = [round(xC - radius), round(yC - radius), round(xC + radius), round(yC + radius)]

Rotate a rectangle until it hits a triangle, and determine the point of intersection

This problem is in 3D space.
There is a rectangle, defined by 4 vertices. We rotate it around one of its sides.
There is a triangle, defined by 3 vertices.
After a full 360 degree rotation, will the rectangle ever intersect/touch the triangle?
If so, what is the angle of rotation at which intersection first occurs? And what is the point of this first intersection?
After thinking about this for a while, it seems like there are 3 main cases:
triangle vertex touches rectangle surface
triangle surface touches rectangle vertex
triangle edge touches rectangle edge
And there are 2 unlikely cases where the two are perpendicular when the intersect:
rectangle edge hits triangle surface
rectangle surface hits triangle edge
However identifying these cases hasn't really gotten me closer to a solution. I'm hoping someone can point me in the right direction for how to solve this problem. I want to solve it fast for a small number of rectangles x a large number of triangles.
Context: the larger problem I'm trying to solve is I want to wrap a rectangle around a closed polygonal mesh. I wish to do this step by step by rotating the rectangle until it intersects, then rotating the remaining rectangle around the intersection point, etc.
When you rotate a rectangle around one of its sides, you get a cylinder. Intersect each of the lines with the cylinder. The position of the intersection points gives you the rotation angles. Since this doesn't catch the case where the triangle is completely contained within the cylinder, test whether the vertices' distance to the cylinder's axis is smaller than the cylinder's radius, too.
Say your rectangle has the vertices A to D. You want to rotate around the side AB. The radius of your cylinder is then r = |AD|.
First, transform the coordinates so that the rectangle is placed with the side that you want to rotate about along the z axis and the adjacent side along the x axis.
A′ = {M} · A = {0, 0, 0}
B′ = {M} · B = {0, 0, |AB|}
C′ = {M} · C = {r, 0, 0}
Apply the same transformation {M} to the vertices of the triangle.
Now find the intersections of all three sides of the triangle with the cylinder. Because the cylinder is aligned to the z axis, the problem can be separated into two subproblems: (1) Find any intersections with the top and bottom surfaces a z == 0 and z == |AB|. (2) Find the intersections with the "coat" of the cylinder; this is the intersection of a line with a circle in the xy plane.
You can then calculate the rotation angles with the tangent function of the y and x coordinates of these points as atan2(y, x).
If you need the coordinates of the intersection points in the original coordinates, don't forget to undo the transformation.

Circle transformation outside of circle

I'm trying to rotate a rectangle based on the position of the mouse inside or outside of the circle.
The way I see it, if I can determine the point on the circle that is closest to the position of the mouse, I can then transform the rectangle along the circle using that point as the target.
I cannot however, figure out how to find that position. I thought that perhaps by using y=mx+b to follow the line from the mouse pos until it hits the point on the circle.
The problem with this however is that I do not have all of the points on the circle and there are hundreds if not thousands of points on the circle.
If the mouse position is outside of a circle, how do I find the point on the circle closest to the mouse-position?
Use math.atan2() to get the angle of the cursor from the center. The circle will be a fixed distance from the center, so you can just convert the angle and distance to a point on the circle with more trig.
angle = math.atan2(ymouse - ycenter, xmouse - xcenter)

Categories