It is currently Tue Dec 10, 2019 9:55 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Vector drawing, manual drawing curve segment selection
PostPosted: Thu Feb 21, 2019 4:32 pm 
Offline
User
User

Joined: Fri Jan 28, 2011 12:26 pm
Posts: 29
Code:
;***********************************
;迷路仟整理 2019.02.21
;矢量绘图_手动绘制曲线段选区
;***********************************

;MovePathCursor是起点,AddPathCurveX3/Y3是终点, AddPathCurveX1/Y1,AddPathCurveX2/Y2是调节点

;-[Enumeration]
Enumeration
   #winScreen
   #cvsScreen
   #tmrScreen
   #fntScreen
EndEnumeration

;-[Structure]
Structure __PointInfo
   X.f
   Y.f
   *pSymmetry.__PointInfo
   *pOriginal.__PointInfo
EndStructure

Structure __BezierInfo
   CurrTrace.__PointInfo      ;描点:终点
   CurrLocus.__PointInfo      ;控点
   NextLocus.__PointInfo      ;控点   
EndStructure

Structure __GraphicsInfo
   *pPoint.__PointInfo
   *pPrevBezier.__GraphicsInfo
   List *pListPoint.__PointInfo()
   List ListBezier.__BezierInfo()
   DynamicIndex.l
   IsClosePath.b
   IsFinishPath.b
EndStructure


;-[Global]
Global _Graphics.__GraphicsInfo

;- **************************
;-[Redraw]
;完成曲线,建立选区
Procedure Redraw_Graphics_FinishPath()
   With _Graphics\ListBezier()
      ;绘制多段曲线组成的选区
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      *pBezier.__BezierInfo = *pFirstBezier
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
         AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
         *pBezier = _Graphics\ListBezier()
      Wend
      FirstElement(_Graphics\ListBezier())
      AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
     
      ;为选区边线间线并做动态处理
      Result$ = PathSegments()
      VectorSourceColor($FFFF8000) 
      StrokePath(1.5)
      AddPathSegments(Result$)
      VectorSourceColor($FF000000)
      DashPath(1.5, 10, #PB_Path_Default, _Graphics\DynamicIndex)
   EndWith
EndProcedure

;封闭曲线段
Procedure Redraw_Graphics_ClosePath()
   With _Graphics\ListBezier()
      ;绘制多段曲线组成的形状
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      *pBezier.__BezierInfo = *pFirstBezier
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
         AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
         *pBezier = _Graphics\ListBezier()
      Wend
      FirstElement(_Graphics\ListBezier())
      AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
      VectorSourceColor($A00000FF)
      StrokePath(1.5)
     
      ;绘制辅助线
      ForEach _Graphics\ListBezier()
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\CurrLocus\x, \CurrLocus\y)
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\NextLocus\x, \NextLocus\y)               
      Next
      VectorSourceColor($80000000)
      DashPath(1.5, 3)

      ;绘制辅助点
      ForEach _Graphics\ListBezier()
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
      Next
      VectorSourceColor($FF808080)
      FillPath() 
   EndWith
   With *pBezier   
      ;绘制当前选中点   
      If _Graphics\pPoint
         *pBezier = _Graphics\pPoint\pOriginal
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
      EndIf
      VectorSourceColor($FFFF8000)
      FillPath()         
   EndWith
EndProcedure

;添加曲线段
Procedure Redraw_Graphics_AddPath()

   With _Graphics\ListBezier()
      ;绘制多段曲线组成的形状
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      *pBezier.__BezierInfo = *pFirstBezier
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
         AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
         *pBezier = _Graphics\ListBezier()
      Wend
      VectorSourceColor($A00000FF)
      StrokePath(1.5)
     
      ;绘制辅助线
      *pBezier = FirstElement(_Graphics\ListBezier())
      MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
      AddPathLine(*pBezier\NextLocus\x, *pBezier\NextLocus\y)
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\CurrLocus\x, \CurrLocus\y)
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\NextLocus\x, \NextLocus\y)               
      Wend
      VectorSourceColor($80000000)
      DashPath(1.5, 3)

      ;绘制辅助点
      *pBezier = FirstElement(_Graphics\ListBezier())
      AddPathBox   (*pBezier\CurrTrace\x-6, *pBezier\CurrTrace\y-6, 12, 12)
      AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
      While NextElement(_Graphics\ListBezier())
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         If _Graphics\ListBezier() <> *pFirstBezier
            AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
         EndIf
         *pBezier = _Graphics\ListBezier()
      Wend
      VectorSourceColor($FF808080)
      FillPath() 
   EndWith 
   
   With *pBezier
      ;绘制当前选中点       
      If _Graphics\pPoint
         *pBezier = _Graphics\pPoint\pOriginal
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         If *pBezier <> *pFirstBezier
            AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
         EndIf
      EndIf
      VectorSourceColor($FFFF8000)
      FillPath()         
   EndWith

EndProcedure

;动态的绘制几何图形
Procedure Redraw_Graphics()
   *pBezier.__BezierInfo
   *pFirstBezier.__BezierInfo
   If StartVectorDrawing(CanvasVectorOutput(#cvsScreen))
      VectorSourceColor($FFFFFFFF)
      FillVectorOutput()
      VectorFont(FontID(#fntScreen), 20)
      VectorSourceColor($FFFF8000)
      MovePathCursor(010, 010)
      DrawVectorText("左键添点描点,右键单击封闭多段曲线! --- 左键双击建立选区,右键双击清空曲线段!")
      Count = ListSize(_Graphics\ListBezier())
      If Count
         If _Graphics\IsFinishPath = #True
            Redraw_Graphics_FinishPath()
         ElseIf _Graphics\IsClosePath = #True
            Redraw_Graphics_ClosePath()
         Else
            Redraw_Graphics_AddPath()
         EndIf
      EndIf
      StopVectorDrawing()
    EndIf
EndProcedure

;- **************************
;-[EventGadget]
Procedure EventGadget_AddPoint(*pPoint.__PointInfo, X, Y, *pOriginal, *pSymmetry)
   *pPoint\X = X
   *pPoint\Y = Y
   *pPoint\pSymmetry = *pSymmetry
   *pPoint\pOriginal = *pOriginal
   AddElement(_Graphics\pListPoint())
   _Graphics\pListPoint() = *pPoint
EndProcedure

Procedure EventGadget_cvsScreen_RightClick()
   If _Graphics\IsClosePath = #False
      *pLastBezier.__BezierInfo  = LastElement(_Graphics\ListBezier())
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      If *pFirstBezier = 0 : ProcedureReturn : EndIf
      With *pFirstBezier
         X = \CurrTrace\x * 2 - \NextLocus\x
         Y = \CurrTrace\y * 2 - \NextLocus\y
         EventGadget_AddPoint(\CurrLocus, X, Y, \CurrTrace, \NextLocus)
         \NextLocus\pSymmetry = \CurrLocus   
         _Graphics\pPoint = \CurrLocus
         _Graphics\pPrevBezier = *pFirstBezier
         Redraw_Graphics()
      EndWith
      _Graphics\IsClosePath = #True
      Redraw_Graphics()
   EndIf
EndProcedure

Procedure EventGadget_cvsScreen_LeftButtonDown()

   If _Graphics\IsFinishPath = #True
      ClearList(_Graphics\pListPoint())
      ClearList(_Graphics\ListBezier())
      _Graphics\pPoint = 0
      _Graphics\IsClosePath  = #False
      _Graphics\IsFinishPath = #False
   EndIf
   X = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseX)
   Y = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseY)
   ;判断光标落点
   ForEach _Graphics\pListPoint()
      *pPoint.__PointInfo = _Graphics\pListPoint()
      If Sqr(Pow(*pPoint\X - X, 2) + Pow(*pPoint\Y - Y, 2)) < 10
         _Graphics\pPoint = *pPoint
         _Graphics\pPoint\x = X
         _Graphics\pPoint\y = Y
         Redraw_Graphics()
         ProcedureReturn
      EndIf
   Next
   If _Graphics\IsClosePath = #True
      ProcedureReturn
   EndIf
   *pBezier.__BezierInfo = AddElement(_Graphics\ListBezier())
   With *pBezier
      ;如果是曲线起点
      If _Graphics\pPrevBezier = 0
         EventGadget_AddPoint(\NextLocus, X, Y, \CurrTrace, 0)
         EventGadget_AddPoint(\CurrTrace, X, Y, \CurrTrace, 0)
         _Graphics\pPoint = \NextLocus
      ;如果是曲线续画
      Else
         EventGadget_AddPoint(\CurrLocus, X, Y, \CurrTrace, \NextLocus)
         EventGadget_AddPoint(\NextLocus, X, Y, \CurrTrace, \CurrLocus)
         EventGadget_AddPoint(\CurrTrace, X, Y, \CurrTrace, 0)
         _Graphics\pPoint = \NextLocus
      EndIf
      _Graphics\pPrevBezier = *pBezier
      Redraw_Graphics()
   EndWith

EndProcedure

Procedure EventGadget_cvsScreen_LeftButtonUp()
   If _Graphics\IsFinishPath = #True : ProcedureReturn : EndIf
   If _Graphics\pPoint
      _Graphics\pPoint\x = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseX)
      _Graphics\pPoint\y = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseY)
      _Graphics\pPoint = 0
      Redraw_Graphics()
   EndIf
EndProcedure

Procedure EventGadget_cvsScreen_MouseMove()
   If _Graphics\IsFinishPath = #True : ProcedureReturn : EndIf
   IsButtonDown = GetGadgetAttribute(#cvsScreen, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
   If IsButtonDown = 0 : ProcedureReturn : EndIf
   If _Graphics\pPoint
      With _Graphics\pPoint
         x = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseX)
         y = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseY)
         If _Graphics\pPoint = \pOriginal
            dx = x - \x
            dy = y - \y
            *pBezier.__BezierInfo = \pOriginal
            If *pBezier\CurrLocus
               *pBezier\CurrLocus\x + dx
               *pBezier\CurrLocus\y + dy
            EndIf
            *pBezier\NextLocus\x + dx
            *pBezier\NextLocus\y + dy
         ElseIf \pSymmetry
            \pSymmetry\x = \pOriginal\x * 2 - x
            \pSymmetry\y = \pOriginal\y * 2 - y
         EndIf
         \x = x
         \y = y
      EndWith
      Redraw_Graphics()
   EndIf
EndProcedure

;画布事件
Procedure EventGadget_cvsScreen()

   Select EventType()
      Case #PB_EventType_LeftDoubleClick
         If _Graphics\IsClosePath = #True
            _Graphics\IsFinishPath = #True
            Redraw_Graphics()     
         EndIf
      Case #PB_EventType_RightDoubleClick
         ClearList(_Graphics\pListPoint())
         ClearList(_Graphics\ListBezier())
         _Graphics\pPoint = 0
         _Graphics\IsClosePath  = #False
         _Graphics\IsFinishPath = #False
         Redraw_Graphics()
     
      Case #PB_EventType_RightClick 
         EventGadget_cvsScreen_RightClick()
      Case #PB_EventType_LeftButtonDown
         EventGadget_cvsScreen_LeftButtonDown()
      Case #PB_EventType_LeftButtonUp
         EventGadget_cvsScreen_LeftButtonUp()
      Case #PB_EventType_MouseMove
         EventGadget_cvsScreen_MouseMove()
   EndSelect
   
EndProcedure

;- **************************
;-[Main]
LoadFont(#fntScreen, "", 12)
If OpenWindow(#winScreen, 0, 0, 800, 550, "矢量绘图_手动绘制曲线段选区", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
   CanvasGadget(#cvsScreen, 0, 0, 800, 550)
   AddWindowTimer(#winScreen, #tmrScreen, 100)
   Repeat
      WinEvent = WindowEvent()
      Select WinEvent
         Case #PB_Event_CloseWindow : IsExitWindow = #True
         Case #PB_Event_Timer
            If EventTimer() = #tmrScreen : _Graphics\DynamicIndex+1 : Redraw_Graphics() : EndIf
         Case #PB_Event_Gadget
            Select EventGadget()
               Case #cvsScreen : EventGadget_cvsScreen()
            EndSelect
      EndSelect
   Until IsExitWindow = #True
EndIf
End



_________________
I came to the ancient oriental country - China
I will PureBasic called B++


Top
 Profile  
Reply with quote  
 Post subject: Re: 矢量绘图_手动绘制曲线段选区
PostPosted: Thu Feb 21, 2019 4:59 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jun 22, 2003 7:43 pm
Posts: 461
Location: Germany, Saarbrücken
This is no coding question. This is spam.

_________________
Electronics, Crazy & Interesting Stuff, all that with text, image and sound? Click here!

The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.


Top
 Profile  
Reply with quote  
 Post subject: Re: 矢量绘图_手动绘制曲线段选区
PostPosted: Thu Feb 21, 2019 10:53 pm 
Offline
Addict
Addict
User avatar

Joined: Fri May 12, 2006 6:51 pm
Posts: 2053
Location: Germany
No Spam... China

Lost and finishing 2019.02.21
vector drawing _ manual drawing curve segment selection

Thanks... Its work 谢谢。 我的工作

Please english (or german)

_________________
My Projects ThreadToGUI / OOP-BaseClass / OOP-BaseClassDispatch / EventDesigner V3
PB v3.30 / v5.70 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace


Top
 Profile  
Reply with quote  
 Post subject: Re: Vector drawing, manual drawing curve segment selection
PostPosted: Fri Feb 22, 2019 1:04 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Apr 26, 2003 2:15 pm
Posts: 841
Location: Cuernavaca, Mexico
Google translated for those of you who are curious... :)

Code:
; =================================================================
;
; Author:     MiLoo   
; Date:       February 21, 2019
; Explain:    Vector drawing, manual drawing curve segment selection
;           
; Search tips:
;
; Saved as:   Drawing Curved Segments.pb     
; =================================================================

;***********************************
; lost road finishing 2019.02.21
; vector drawing _ manual drawing curve segment selection
;***********************************

; MovePathCursor (Is the starting point)
; AddPathCurveX3/Y3 (Is the end)
; AddPathCurveX1/Y1 and
; AddPathCurveX2/Y2 (Are the adjustment points)

;-[Enumeration]
Enumeration
   #winScreen
   #cvsScreen
   #tmrScreen
   #fntScreen
EndEnumeration

;-[Structure]
Structure __PointInfo
   X.f
   Y.f
   *pSymmetry.__PointInfo
   *pOriginal.__PointInfo
EndStructure

Structure __BezierInfo
   CurrTrace.__PointInfo      ; point: end point
   CurrLocus.__PointInfo      ; Control point
   NextLocus.__PointInfo      ; Control point   
EndStructure

Structure __GraphicsInfo
   *pPoint.__PointInfo
   *pPrevBezier.__GraphicsInfo
   List *pListPoint.__PointInfo()
   List ListBezier.__BezierInfo()
   DynamicIndex.l
   IsClosePath.b
   IsFinishPath.b
EndStructure


;-[Global]
Global _Graphics.__GraphicsInfo

;- **************************
;-[Redraw]
;Complete the curve And establish a selection
Procedure Redraw_Graphics_FinishPath()
   With _Graphics\ListBezier()
      ; draw a selection of multi-segment curves
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      *pBezier.__BezierInfo = *pFirstBezier
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
         AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
         *pBezier = _Graphics\ListBezier()
      Wend
      FirstElement(_Graphics\ListBezier())
      AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
     
     ; for the inter-line line and dynamic processing
      Result$ = PathSegments()
      VectorSourceColor($FFFF8000) 
      StrokePath(1.5)
      AddPathSegments(Result$)
      VectorSourceColor($FF000000)
      DashPath(1.5, 10, #PB_Path_Default, _Graphics\DynamicIndex)
   EndWith
EndProcedure

; Closed curve segment
Procedure Redraw_Graphics_ClosePath()
   With _Graphics\ListBezier()
     ; draw a shape composed of multiple segments
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      *pBezier.__BezierInfo = *pFirstBezier
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
         AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
         *pBezier = _Graphics\ListBezier()
      Wend
      FirstElement(_Graphics\ListBezier())
      AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
      VectorSourceColor($A00000FF)
      StrokePath(1.5)
     
     ; draw guides
      ForEach _Graphics\ListBezier()
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\CurrLocus\x, \CurrLocus\y)
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\NextLocus\x, \NextLocus\y)               
      Next
      VectorSourceColor($80000000)
      DashPath(1.5, 3)

      ; drawing auxiliary points
      ForEach _Graphics\ListBezier()
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
      Next
      VectorSourceColor($FF808080)
      FillPath() 
   EndWith
   With *pBezier   
      ; draw the currently selected point
      If _Graphics\pPoint
         *pBezier = _Graphics\pPoint\pOriginal
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
      EndIf
      VectorSourceColor($FFFF8000)
      FillPath()         
   EndWith
EndProcedure

; add curve segment
Procedure Redraw_Graphics_AddPath()

   With _Graphics\ListBezier()
    ; draw a shape composed of multiple segments
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      *pBezier.__BezierInfo = *pFirstBezier
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
         AddPathCurve(*pBezier\NextLocus\x, *pBezier\NextLocus\y, \CurrLocus\x, \CurrLocus\y, \CurrTrace\x, \CurrTrace\y)
         *pBezier = _Graphics\ListBezier()
      Wend
      VectorSourceColor($A00000FF)
      StrokePath(1.5)
     
     ; draw guides
      *pBezier = FirstElement(_Graphics\ListBezier())
      MovePathCursor(*pBezier\CurrTrace\x, *pBezier\CurrTrace\y)
      AddPathLine(*pBezier\NextLocus\x, *pBezier\NextLocus\y)
      While NextElement(_Graphics\ListBezier())
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\CurrLocus\x, \CurrLocus\y)
         MovePathCursor(\CurrTrace\x, \CurrTrace\y)
         AddPathLine(\NextLocus\x, \NextLocus\y)               
      Wend
      VectorSourceColor($80000000)
      DashPath(1.5, 3)

     ; drawing auxiliary points
      *pBezier = FirstElement(_Graphics\ListBezier())
      AddPathBox   (*pBezier\CurrTrace\x-6, *pBezier\CurrTrace\y-6, 12, 12)
      AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
      While NextElement(_Graphics\ListBezier())
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         If _Graphics\ListBezier() <> *pFirstBezier
            AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
         EndIf
         *pBezier = _Graphics\ListBezier()
      Wend
      VectorSourceColor($FF808080)
      FillPath() 
   EndWith 
   
   With *pBezier
    ; draw the currently selected point   
      If _Graphics\pPoint
         *pBezier = _Graphics\pPoint\pOriginal
         AddPathBox   (\CurrTrace\x-6, \CurrTrace\y-6, 12, 12)
         AddPathCircle(\NextLocus\x+0, \NextLocus\y+0, 05)
         If *pBezier <> *pFirstBezier
            AddPathCircle(\CurrLocus\x+0, \CurrLocus\y+0, 05)
         EndIf
      EndIf
      VectorSourceColor($FFFF8000)
      FillPath()         
   EndWith

EndProcedure

; dynamically draw geometry
Procedure Redraw_Graphics()
   *pBezier.__BezierInfo
   *pFirstBezier.__BezierInfo
   If StartVectorDrawing(CanvasVectorOutput(#cvsScreen))
      VectorSourceColor($FFFFFFFF)
      FillVectorOutput()
      VectorFont(FontID(#fntScreen), 20)
      VectorSourceColor($FFFF8000)
      MovePathCursor(010, 010)
      DrawVectorText("Left click to add a point, right click to close the multi-segment curve! --- Left-click to create a selection, right-click to clear the curve segment!")
      Count = ListSize(_Graphics\ListBezier())
      If Count
         If _Graphics\IsFinishPath = #True
            Redraw_Graphics_FinishPath()
         ElseIf _Graphics\IsClosePath = #True
            Redraw_Graphics_ClosePath()
         Else
            Redraw_Graphics_AddPath()
         EndIf
      EndIf
      StopVectorDrawing()
    EndIf
EndProcedure

;- **************************
;-[EventGadget]
Procedure EventGadget_AddPoint(*pPoint.__PointInfo, X, Y, *pOriginal, *pSymmetry)
   *pPoint\X = X
   *pPoint\Y = Y
   *pPoint\pSymmetry = *pSymmetry
   *pPoint\pOriginal = *pOriginal
   AddElement(_Graphics\pListPoint())
   _Graphics\pListPoint() = *pPoint
EndProcedure

Procedure EventGadget_cvsScreen_RightClick()
   If _Graphics\IsClosePath = #False
      *pLastBezier.__BezierInfo  = LastElement(_Graphics\ListBezier())
      *pFirstBezier.__BezierInfo = FirstElement(_Graphics\ListBezier())
      If *pFirstBezier = 0 : ProcedureReturn : EndIf
      With *pFirstBezier
         X = \CurrTrace\x * 2 - \NextLocus\x
         Y = \CurrTrace\y * 2 - \NextLocus\y
         EventGadget_AddPoint(\CurrLocus, X, Y, \CurrTrace, \NextLocus)
         \NextLocus\pSymmetry = \CurrLocus   
         _Graphics\pPoint = \CurrLocus
         _Graphics\pPrevBezier = *pFirstBezier
         Redraw_Graphics()
      EndWith
      _Graphics\IsClosePath = #True
      Redraw_Graphics()
   EndIf
EndProcedure

Procedure EventGadget_cvsScreen_LeftButtonDown()

   If _Graphics\IsFinishPath = #True
      ClearList(_Graphics\pListPoint())
      ClearList(_Graphics\ListBezier())
      _Graphics\pPoint = 0
      _Graphics\IsClosePath  = #False
      _Graphics\IsFinishPath = #False
   EndIf
   X = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseX)
   Y = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseY)
  ; judge the cursor to drop
   ForEach _Graphics\pListPoint()
      *pPoint.__PointInfo = _Graphics\pListPoint()
      If Sqr(Pow(*pPoint\X - X, 2) + Pow(*pPoint\Y - Y, 2)) < 10
         _Graphics\pPoint = *pPoint
         _Graphics\pPoint\x = X
         _Graphics\pPoint\y = Y
         Redraw_Graphics()
         ProcedureReturn
      EndIf
   Next
   If _Graphics\IsClosePath = #True
      ProcedureReturn
   EndIf
   *pBezier.__BezierInfo = AddElement(_Graphics\ListBezier())
   With *pBezier
      ; If it is the starting point of the curve
      If _Graphics\pPrevBezier = 0
         EventGadget_AddPoint(\NextLocus, X, Y, \CurrTrace, 0)
         EventGadget_AddPoint(\CurrTrace, X, Y, \CurrTrace, 0)
         _Graphics\pPoint = \NextLocus
      ;If it is a sequel
      Else
         EventGadget_AddPoint(\CurrLocus, X, Y, \CurrTrace, \NextLocus)
         EventGadget_AddPoint(\NextLocus, X, Y, \CurrTrace, \CurrLocus)
         EventGadget_AddPoint(\CurrTrace, X, Y, \CurrTrace, 0)
         _Graphics\pPoint = \NextLocus
      EndIf
      _Graphics\pPrevBezier = *pBezier
      Redraw_Graphics()
   EndWith

EndProcedure

Procedure EventGadget_cvsScreen_LeftButtonUp()
   If _Graphics\IsFinishPath = #True : ProcedureReturn : EndIf
   If _Graphics\pPoint
      _Graphics\pPoint\x = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseX)
      _Graphics\pPoint\y = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseY)
      _Graphics\pPoint = 0
      Redraw_Graphics()
   EndIf
EndProcedure

Procedure EventGadget_cvsScreen_MouseMove()
   If _Graphics\IsFinishPath = #True : ProcedureReturn : EndIf
   IsButtonDown = GetGadgetAttribute(#cvsScreen, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
   If IsButtonDown = 0 : ProcedureReturn : EndIf
   If _Graphics\pPoint
      With _Graphics\pPoint
         x = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseX)
         y = GetGadgetAttribute(#cvsScreen, #PB_Canvas_MouseY)
         If _Graphics\pPoint = \pOriginal
            dx = x - \x
            dy = y - \y
            *pBezier.__BezierInfo = \pOriginal
            If *pBezier\CurrLocus
               *pBezier\CurrLocus\x + dx
               *pBezier\CurrLocus\y + dy
            EndIf
            *pBezier\NextLocus\x + dx
            *pBezier\NextLocus\y + dy
         ElseIf \pSymmetry
            \pSymmetry\x = \pOriginal\x * 2 - x
            \pSymmetry\y = \pOriginal\y * 2 - y
         EndIf
         \x = x
         \y = y
      EndWith
      Redraw_Graphics()
   EndIf
EndProcedure

;Canvas event
Procedure EventGadget_cvsScreen()

   Select EventType()
      Case #PB_EventType_LeftDoubleClick
         If _Graphics\IsClosePath = #True
            _Graphics\IsFinishPath = #True
            Redraw_Graphics()     
         EndIf
      Case #PB_EventType_RightDoubleClick
         ClearList(_Graphics\pListPoint())
         ClearList(_Graphics\ListBezier())
         _Graphics\pPoint = 0
         _Graphics\IsClosePath  = #False
         _Graphics\IsFinishPath = #False
         Redraw_Graphics()
     
      Case #PB_EventType_RightClick 
         EventGadget_cvsScreen_RightClick()
      Case #PB_EventType_LeftButtonDown
         EventGadget_cvsScreen_LeftButtonDown()
      Case #PB_EventType_LeftButtonUp
         EventGadget_cvsScreen_LeftButtonUp()
      Case #PB_EventType_MouseMove
         EventGadget_cvsScreen_MouseMove()
   EndSelect
   
EndProcedure

;- **************************
;-[Main]
LoadFont(#fntScreen, "", 12)
If OpenWindow(#winScreen, 0, 0, 800, 550, "Vector drawing... manual drawing curve segment selection", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
   CanvasGadget(#cvsScreen, 0, 0, 800, 550)
   AddWindowTimer(#winScreen, #tmrScreen, 100)
   Repeat
      WinEvent = WindowEvent()
      Select WinEvent
         Case #PB_Event_CloseWindow : IsExitWindow = #True
         Case #PB_Event_Timer
            If EventTimer() = #tmrScreen : _Graphics\DynamicIndex+1 : Redraw_Graphics() : EndIf
         Case #PB_Event_Gadget
            Select EventGadget()
               Case #cvsScreen : EventGadget_cvsScreen()
            EndSelect
      EndSelect
   Until IsExitWindow = #True
EndIf
End


_________________
- It was too lonely at the top.

Current Machine: Win 10 Pro 64-bit, Dual Xeon E5-2670, 64 gigs ram, Geforce GTX 1660 Ti w/6 gigs ram


Top
 Profile  
Reply with quote  
 Post subject: Re: Vector drawing, manual drawing curve segment selection
PostPosted: Thu Feb 28, 2019 1:05 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4542
Location: Lyon - France
Works fine thanks 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Vector drawing, manual drawing curve segment selection
PostPosted: Thu Feb 28, 2019 5:31 pm 
Offline
Addict
Addict

Joined: Fri Nov 09, 2012 11:04 pm
Posts: 1710
Location: Uttoxeter, UK
@MiLoo,
Nice. Thank you for sharing.
Works on my MacBook Pro, too.

@blueb,
Thank you for taking the trouble to translate.

_________________
DE AA EB


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye