Middlepoint on a curve created by AddPathCurve

Just starting out? Need help? Post your questions and find answers here.
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Middlepoint on a curve created by AddPathCurve

Post by Didelphodon »

Guys,

for my tool ProcDOT I switched to the new VectorDrawing library (which is great, btw.) to draw those bezier-curved graph-edges. So far so good, though I needed some time to understand how to use the AddPathCurve instruction for a curve with an undefined number of points, I now have a problem that I seem to find no/to be able to develop a solution for: I need to find the middle of such a curved path - actually I need the middlepoint ON the path. There I want to put the label of the edge. And this brings up another problem: I furthermore need to rotate/fit the label (which is text) to this middlepoint to perfectly fit the curve. The most awesome thing would be to have the label (text) following the curved path right in the middle. However, if that's not enough, another thing is that the solution would need to have a performance which is top and - last but not least - it needs to run on Windows and Linux as well.

Any ideas how to accomplish this task?

Thx in advance,

Didelphodon
Go, tell it on the mountains.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by IdeasVacuum »

...It sounds like a trigonometry job.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by Didelphodon »

IdeasVacuum wrote:...It sounds like a trigonometry job.
With a bezier curve?!
Go, tell it on the mountains.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Middlepoint on a curve created by AddPathCurve

Post by Little John »

Didelphodon wrote:I need to find the middle of such a curved path - actually I need the middlepoint ON the path. There I want to put the label of the edge.
Have a look at De Casteljau's algorithm (for t = 0.5).
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by Didelphodon »

Little John wrote:
Didelphodon wrote:I need to find the middle of such a curved path - actually I need the middlepoint ON the path. There I want to put the label of the edge.
Have a look at De Casteljau's algorithm (for t = 0.5).
Hard stuff - I will definitely need some time to read/think that through ;-)

Thx, though
Go, tell it on the mountains.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Middlepoint on a curve created by AddPathCurve

Post by srod »

I've never studied Bezier curves in much detail, but the parametric equations are straight forward enough. Now, it is clear that you have to be precise by what you mean by the mid-point? Do you mean the point generated by simply putting t=1/2 (which is straight forward to do) or do you mean the point which splits the Bezier into equal lengths (in the sense of the length of a curve - calculus) ? It is not clear to me that these will yield the same point in anything but the simplest cases. One thing is for sure though; putting t=1/2 will be a darn sight easier than attempting to determine the second case! :)

Obtaining the gradients at any point is also straight forward.

Let us know when you determine exactly which 'mid point' you require?
I may look like a mule, but I'm not a complete ass.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by Fred »

It's probably a bit overkill, but the Spline lib has the needed command: https://www.purebasic.com/documentation ... pline.html. You will need a 3D screen and the 3D lib.
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by bbanelli »

Fred wrote:It's probably a bit overkill, but the Spline lib has the needed command: https://www.purebasic.com/documentation ... pline.html. You will need a 3D screen and the 3D lib.
Speaking of, in Spline.pb example, on 5.42 b3, Windows 7 x64, Quadro FX600, on PB x86 I get IMA on line 124

Code: Select all

TimeSinceLastFrame = RenderWorld() / 1000
and on x64 just a crash with the following info

Code: Select all

Problem signature:
  Problem Event Name:	APPCRASH
  Application Name:	PureBasic_Compilation1.exe
  Application Version:	0.0.0.0
  Application Timestamp:	56cb4b04
  Fault Module Name:	Engine3D.dll
  Fault Module Version:	0.0.0.0
  Fault Module Timestamp:	56c344a1
  Exception Code:	c0000005
  Exception Offset:	0000000000606b5c
  OS Version:	6.1.7601.2.1.0.256.1
  Locale ID:	1050
  Additional Information 1:	23e8
  Additional Information 2:	23e8e6edfc31403d602c627cfb4bdb38
  Additional Information 3:	624a
  Additional Information 4:	624a1efa6dcd5ada4631dc2f8c18ad55

Read our privacy statement online:
  http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409

If the online privacy statement is not available, please read our privacy statement offline:
  C:\Windows\system32\en-US\erofflps.txt
Tried same example on Linux with 5.41 LTS and works without a problem. Just as a heads up, I'm not confident enough in 3D to post it as a bug. :)
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by Fred »

Seems like RenderWorld() returns 0 for you (can you check ?). It shouldn't indeed, may be a drivers issue. Seems to run OK hereon Win64 + AMD
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by bbanelli »

Fred wrote:Seems like RenderWorld() returns 0 for you (can you check ?). It shouldn't indeed, may be a drivers issue. Seems to run OK hereon Win64 + AMD
RenderWorld() "returns" IMA. :)

On x64, it won't even get to that part of code in debugger.

Can this (x86 code) give you some additional insight? http://imgur.com/ctFTuYU

I doubt it's drivers issue, I use stable Quadro ODE 354.56 drivers.
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by DK_PETER »

bbanelli wrote:
Fred wrote:Seems like RenderWorld() returns 0 for you (can you check ?). It shouldn't indeed, may be a drivers issue. Seems to run OK hereon Win64 + AMD
RenderWorld() "returns" IMA. :)

On x64, it won't even get to that part of code in debugger.

Can this (x86 code) give you some additional insight? http://imgur.com/ctFTuYU

I doubt it's drivers issue, I use stable Quadro ODE 354.56 drivers.
A couple of suggestions:

1. Could you try to reinstall DirectX 9c drivers and try again? You need them in Windows 10 too.
2. See if you can run it using OpenGL in subsystem.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Little John
Addict
Addict
Posts: 4777
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Middlepoint on a curve created by AddPathCurve

Post by Little John »

srod wrote:Now, it is clear that you have to be precise by what you mean by the mid-point? Do you mean the point generated by simply putting t=1/2 (which is straight forward to do) or do you mean the point which splits the Bezier into equal lengths (in the sense of the length of a curve - calculus) ? It is not clear to me that these will yield the same point in anything but the simplest cases. One thing is for sure though; putting t=1/2 will be a darn sight easier than attempting to determine the second case! :)
Previously, it seemed to me that both cases mentioned by you are always identical. But the following example shows that that is not true. :-(

Code: Select all

; tested with PB 5.42 beta 2 x64 on Windows 10

EnableExplicit

Structure PointD
   x.d
   y.d
EndStructure


Procedure DeCasteljau (x0.d, y0.d, x1.d, y1.d, x2.d, y2.d, x3.d, y3.d, t.d, *p.PointD)
   ; -- De Casteljau's algorithm
   ; <http://stackoverflow.com/questions/14174252/how-to-find-out-y-coordinate-of-specific-point-in-bezier-curve-in-canvas>, 2016-02-22
   ; in : x0, y0, x1, y1, x2, y2, x3, y3: see PB's AddPathCurve()
   ;      (x0, y0 = current position of the cursor)
   ;      t: rational number from the interval [0.0; 1.0]
   ; out: *p: Coordinates of the wanted point
   Protected.d Ax, Ay, Bx, By, Cx, Cy, Dx, Dy, Ex, Ey
   
   Ax = (1.0 - t) * x0  +  t * x1
   Ay = (1.0 - t) * y0  +  t * y1
   Bx = (1.0 - t) * x1  +  t * x2
   By = (1.0 - t) * y1  +  t * y2
   Cx = (1.0 - t) * x2  +  t * x3 
   Cy = (1.0 - t) * y2  +  t * y3
   
   Dx = (1.0 - t) * Ax  +  t * Bx
   Dy = (1.0 - t) * Ay  +  t * By
   Ex = (1.0 - t) * Bx  +  t * Cx
   Ey = (1.0 - t) * By  +  t * Cy
   
   *p\x = (1.0 - t) * Dx  +  t * Ex
   *p\y = (1.0 - t) * Dy  +  t * Ey
EndProcedure


; -- Demo
Define.d x0, y0, x1, y1, x2, y2, x3, y3, t
Define.i i
Define p.PointD

x0 =  50 : y0 = 100
x1 =  90 : y1 =  30
x2 = 250 : y2 = 180
x3 = 350 : y3 = 100

OpenWindow(0, 0, 0, 400, 200, "De Casteljau's algorithm", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 400, 200)

; AddPathCurve(): red line
If StartVectorDrawing(CanvasVectorOutput(0))
   MovePathCursor(x0, y0)
   AddPathCurve(x1, y1, x2, y2, x3, y3)
   VectorSourceColor(RGBA(255, 0, 0, 255))
   StrokePath(10)
   StopVectorDrawing()
EndIf

; DeCasteljau(): green and blue circles
If StartVectorDrawing(CanvasVectorOutput(0))
   For i = 0 To 4
      t = i / 10.0
      DeCasteljau(x0, y0, x1, y1, x2, y2, x3, y3, t, @p)
      AddPathCircle(p\x, p\y, 5)
   Next
   VectorSourceColor(RGBA(0, 255, 0, 255))
   StrokePath(2)
   
   t = 0.5
   DeCasteljau(x0, y0, x1, y1, x2, y2, x3, y3, t, @p)
   AddPathCircle(p\x, p\y, 5)
   VectorSourceColor(RGBA(0, 0, 255, 255))
   StrokePath(2)
   
   For i = 6 To 10
      t = i / 10.0
      DeCasteljau(x0, y0, x1, y1, x2, y2, x3, y3, t, @p)
      AddPathCircle(p\x, p\y, 5)
   Next
   VectorSourceColor(RGBA(0, 255, 0, 255))
   StrokePath(2)
   
   StopVectorDrawing()
EndIf

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Image
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by Didelphodon »

srod wrote:I've never studied Bezier curves in much detail, but the parametric equations are straight forward enough. Now, it is clear that you have to be precise by what you mean by the mid-point? Do you mean the point generated by simply putting t=1/2 (which is straight forward to do) or do you mean the point which splits the Bezier into equal lengths (in the sense of the length of a curve - calculus) ? It is not clear to me that these will yield the same point in anything but the simplest cases. One thing is for sure though; putting t=1/2 will be a darn sight easier than attempting to determine the second case! :)

Obtaining the gradients at any point is also straight forward.

Let us know when you determine exactly which 'mid point' you require?
Generally speaking I need the second kind - the point which splits the curve into two equal lengths. However, if there's a significant difference between those two options in terms of performance I'd also be happy with the faster (probably easier one).
Go, tell it on the mountains.
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by Didelphodon »

@Little John: Thx for the example, this might become very handy for my project!
Go, tell it on the mountains.
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Re: Middlepoint on a curve created by AddPathCurve

Post by Didelphodon »

Fred wrote:It's probably a bit overkill, but the Spline lib has the needed command: https://www.purebasic.com/documentation ... pline.html. You will need a 3D screen and the 3D lib.
Interesting idea - actually I never even played with the thought of using the 3D engine for this 2D topic. However, I think the whole project is already way too far in terms of development to take a 180 degree corner.
Go, tell it on the mountains.
Post Reply