Page 1 of 3

Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 2:41 pm
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

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 3:57 pm
by IdeasVacuum
...It sounds like a trigonometry job.

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 4:10 pm
by Didelphodon
IdeasVacuum wrote:...It sounds like a trigonometry job.
With a bezier curve?!

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 4:24 pm
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).

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 5:08 pm
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

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 5:19 pm
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?

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 6:01 pm
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.

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 6:54 pm
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. :)

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 7:49 pm
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

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 8:15 pm
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.

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 8:24 pm
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.

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 8:37 pm
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

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 8:39 pm
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).

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 8:46 pm
by Didelphodon
@Little John: Thx for the example, this might become very handy for my project!

Re: Middlepoint on a curve created by AddPathCurve

Posted: Mon Feb 22, 2016 8:49 pm
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.