Help making a curve from a specific point.
-
Folks,
I am trying to write some code to draw a map from an external data source. I'm using QGraphicsView and PyQt but am having difficulty getting the code that draws arcs right. My problem is that I start off with a spec that is unclear and I'm not entirely sure how the arc code in qt behaves either.
Initial parameters: an X,Y location on a plane; an arc length (unknown if chord or circumference); a tangent angle to the arc at XY; a curvature, believed to be 1/radius; a "sign" (1 or -1, possibly is the arc "left" or "right").
I have drawn a pic showing an example arc here:
!http://static.inky.ws/image/2912/image.jpg(Maps)!
The code below is the guts of what I have so far, and it draws the following map from my test data, in which the light grey boxes represent the QT Box parameter and the green boxes represent the extent of the area the map is supposed to occupy. A part of the problem is that things are rotated, but that is not all of it:
!http://static.inky.ws/image/2913/image.jpg(Bad Map)!
The map should look like this:
!http://static.inky.ws/image/2914/image.jpg(Correct Map)!
Can anyone suggest where I should look next for solutions?
Thanks for your help,
Ruth@elif (segment.curveType() == CURVE_ARC):
inputs
x, y = segment.getX(), segment.getZ() # UNITS => METRES
slen = segment.getLen() # length in metres
ang = segment.getATan2() # angle in radians.. unknown reference
arc = segment.getArc() # curvature
sign = segment.getSign() # unknown purposegiven curvature, which I believe is 1/radius, so convert back.
r = 1/arc
find circle centre: at 90' to tangent and radius length
cx, cy = math.floor(x + math.cos(ang + pb2)*r), math.floor(y + math.sin(ang + pb2)*r)
width and height of enclosing box is 2x radius:
sz = 2*r
top left coordinate of box is at cx-r, cy-r
tl_x, tl_y = cx - r, cy - r
box = QtCore.QRectF(tl_x,tl_y, sz, sz)
#sweep = slen / ( 1 / arc)
sweep = slen * arc
sweep_deg = -(360.0 * sweep) / (2 * math.pi)tang_deg = (360.0 * ang) / (2 * math.pi)
start_ang = -(tang_deg)path = QtGui.QPainterPath()
path.arcMoveTo(box, start_ang)
path.arcTo(box, start_ang, sweep_deg)self.scene.addPath(path, self.trackPen)
#self.scene.addRect(box, self.constructPen)
@ -
The API simply has no method to start an arc from a point, you will have to reverse engineer a method. I suspect you need the type of arc that is typically found in CAD software like SolidWorks or Inventor - two points and radius. You will basically have to implement an adapter method to calculate a Qt style arc from the style of arc you need and pass the data to the Qt method. I could tell you how but since this looks like a homework, I'll let you do it the hard way ;)
-
utcenter, I am quite aware of what you said re Qt, and this certainly isn't "homework"! I did my degree quite some time back now... just not in maths.
My purpose in writing this post was to show the reverse-engineering method I have been trying, and how it isn't working in the hope someone will be able to assist.
You're right, the "CAD" type arc would suit very well. I have wondered whether there are ways to draw an arc that use curvature and tangent directly, rather than via the radius.. am I right? If so would my best bet be to create a new Graphics Item using those parameters as input and doing the drawing in that?
Ruth
-
The images don't load from here.
-
Sorry, the site inky.ws that I used for the images seems to be offline at the moment, I don't know why.
Hopefully it will return soon.