Vector Drawing Change coordinates system

Just starting out? Need help? Post your questions and find answers here.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Vector Drawing Change coordinates system

Post by IdeasVacuum »

It's relatively easy to draw shapes, especially when each path line is relative to the previous, in the default coordinate system.

However, I need to import line drawings whose points are defined in a typical CAD coordinate system:

Image


How do I move and 'flip' the default system to work as above, with the points of each line being absolute?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4663
Joined: Sun Apr 12, 2009 6:27 am

Re: Vector Drawing Change coordinates system

Post by RASHAD »

Hi IdeasVacuum
Long time no see
I am Not sure about your aim
But Next could be a start

Code: Select all

If OpenWindow(0, 0, 0, 450, 300, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 0, 0, 450, 300)

    If StartVectorDrawing(CanvasVectorOutput(0))
      
      AddPathSegments("M 40 20 L 120 20 L 120 60 L 200 60 L 200 100 L 280 100 L 280 140 L 360 140 L 360 180")
      VectorSourceColor(RGBA(255, 0, 0, 255))
      StrokePath(5, #PB_Path_RoundCorner)
      
      TranslateCoordinates(30, 30)      
      AddPathSegments("M 40 20 L 120 20 L 120 60 L 200 60 L 200 100 L 280 100 L 280 140 L 360 140 L 360 180")
      VectorSourceColor(RGBA(0, 0, 255, 255))
      StrokePath(5, #PB_Path_RoundCorner)
      StopVectorDrawing()
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
  EndIf
Egypt my love
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Vector Drawing Change coordinates system

Post by Marc56us »

I'm not sure, but the main difficulty is that CAD programs put the origin at the bottom left (as in mathematics) and Y in positive value upwards while the PB Vector lib puts the origin at the top left and the positive values to the bottom.

Neither the coordinate translation function nor the mirror function can do this (as I read in the doc)

I think it is therefore necessary to invert Y by setting the maximum value of the drawing area and subtract the value of Y each time.

Maybe with a macro ?

Code: Select all

New_Y = PB_Y - DXF_Y
Where:
PB_Y = bottom left of drawing area
DXF_Y = Value of Y in exported file (DXF ?)

:wink:
infratec
Always Here
Always Here
Posts: 6874
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Vector Drawing Change coordinates system

Post by infratec »

And it is possible that the coordinates from the CAD file are in mm or something else, normaly not in pixel.
So you have to transform them.

Have you a small example CAD file?
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Vector Drawing Change coordinates system

Post by Marc56us »

infratec wrote:And it is possible that the coordinates from the CAD file are in mm or something else, normaly not in pixel.
So you have to transform them.
Yes, but on this side, this should not be a problem, because in most CAD programs (using the metric system) we work in "drawing units" (dots)
The unit is only given a value at the time of quotation or printing. This allows you to use the same plan for several uses and zoom in and out as much as you want.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vector Drawing Change coordinates system

Post by IdeasVacuum »

Hi Guys

Yeah - I was hopeful about the coordinate system but if that's a no, I shall invert all the Y values on import. I already have to swap axis in the OpenGL Gadget, which surprised me given that nearly all CAD-CAM programs use OpenGL.

The Vector Lib does allow different units, including mm. For the purposes of displaying the shape and it's vicinity to other shapes, pixels are fine.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Vector Drawing Change coordinates system

Post by Marc56us »

IdeasVacuum wrote: Yeah - I was hopeful about the coordinate system but if that's a no, I shall invert all the Y values on import.
Do not invert the Y values (you would get a mirror, so the text (cotations) would be unusable)
Subtract all Y values from the Y value at the bottom of the drawing area

New_Y = Heigh_of_drawing_area - Y

Quick and dirty exemple :oops:

Code: Select all

; SVG to PB Vector Drawing

; How exported CAO look like (in SVG)
; Rectangular triangle exported in SVG by GCAD
; 90° angle at bottom left (at 0.0) 
; |\
; | \
; +--  I'm poor in ascii art :'(
;
; <?xml version="1.0" encoding="UTF-8"?>
; <!-- 2019-11-08 14:51:23 Generated by QCAD SVG Exporter -->
; <svg width="30" height="30" viewBox="0 -30 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg" style="stroke-linecap:round;stroke-linejoin:round;fill:none">
;     <g transform="scale(1,-1)">
;         <!-- Ligne -->
;         <path d="M0,0 L30,0 " style="stroke:#000000;stroke-width:0.25;"/>
;         <!-- Ligne -->
;         <path d="M30,0 L0,30 " style="stroke:#000000;stroke-width:0.25;"/>
;         <!-- Ligne -->
;         <path d="M0,30 L0,0 " style="stroke:#000000;stroke-width:0.25;"/>
;     </g>
; </svg>

; SVG: x, y
;  0,0  to 30,0
; 30,0  to  0,30
;  0,30 to  0,0

EnableExplicit

Structure Type_Line
    X_From.i
    Y_From.i
    X_To.i
    Y_To.i
EndStructure
NewList Line_XY.Type_Line()

Restore Draw:

Define i
For i = 1 To 3
    AddElement(Line_XY())
    With Line_XY()
        Read.i \X_From
        Read.i \Y_From 
        Read.i \X_To
        Read.i \Y_To
    EndWith
Next

OpenWindow(0, 0, 0, 540, 540, "CAD 2 PB Vector", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 10, 10, 520, 520)

If StartVectorDrawing(CanvasVectorOutput(0))
    TranslateCoordinates(10, 10)
    FirstElement(Line_XY())
    ; Origine PB
    ForEach Line_XY()
        With Line_XY()
            MovePathCursor(\X_From, \Y_From)
            AddPathLine(\X_To, \Y_To)
        EndWith
    Next
    VectorSourceColor(RGBA(0, 0, 255, 255))
    StrokePath(3)
    
    ; Corrected
    Define New_Y = 500
    FirstElement(Line_XY())
    ForEach Line_XY()
        With Line_XY()
            MovePathCursor(\X_From, New_Y - \Y_From)
            AddPathLine(\X_To, New_Y - \Y_To)
        EndWith
    Next
    VectorSourceColor(RGBA(255, 0, 0, 255))
    StrokePath(3)
    
    StopVectorDrawing()
EndIf

Repeat
    Define Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

End

DataSection
    Draw:
    Data.i  0,    0, 300, 0
    Data.i 300,   0,   0, 300
    Data.i  0,  300,   0, 0
EndDataSection
(In blue the drawing as PB traces it with the exported values and in red the rectified drawing)
Image
I didn't test with text, but it should stay straight and wouldn't mirror.

:)
User avatar
skywalk
Addict
Addict
Posts: 3998
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Vector Drawing Change coordinates system

Post by skywalk »

IdeasVacuum wrote:The Vector Lib does allow different units, including mm. For the purposes of displaying the shape and it's vicinity to other shapes, pixels are fine.
This is a BIG no no if you are dealing with accuracy and object intersections. You must use integer math and/or scale your drawing units way above the limited pixels within the viewable area.
If you are just attempting a gross view, then pixels are fine.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
mk-soft
Always Here
Always Here
Posts: 5404
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Vector Drawing Change coordinates system

Post by mk-soft »

If you don't have to write text, FlipCoordinatesY(...) should work.
The angles are also correct according to flip coordinates.

Update v0.2
- Macro DrawVectorText added

Update v0.4
- Added LoadFont

Update v0.5
- Bugfix DrawVectorText.

Code: Select all

;-TOP
; Flip Y-Coordinates by mk-soft, v0.6

EnableExplicit

Global _IsFlipped_, _OldY_.d

Macro _PB_(Function)
  Function
EndMacro

Macro BeginFlipCoordinates()
  FlipCoordinatesY(VectorOutputHeight() * 0.5) : _IsFlipped_ = #True
EndMacro

Macro EndFlipCoordinates()
  _PB_(ResetCoordinates)() : _IsFlipped_ = #False
EndMacro

Macro ResetCoordinates(_Value_=#PB_Coordinate_User)
  _PB_(ResetCoordinates)(_Value_) : If _IsFlipped_ : FlipCoordinatesY(VectorOutputHeight() * 0.5, _Value_) : EndIf
EndMacro

Macro DrawVectorText(_Text_)
  If _IsFlipped_
    _OldY_ = PathCursorY()
    FlipCoordinatesY(_OldY_) : _PB_(DrawVectorText)(_Text_) : FlipCoordinatesY(_OldY_)
  Else
    _PB_(DrawVectorText)(_Text_)
  EndIf
EndMacro

Define i

If OpenWindow(0, 0, 0, 450, 300, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, 450, 300)
  LoadFont(0, "Impact", 11)
  
  If StartVectorDrawing(CanvasVectorOutput(0))
    VectorFont(FontID(0))
    
    MovePathCursor(10, 10)
    DrawVectorText("Flip Coordinates Example")
    
    BeginFlipCoordinates()
    
    ; Part 1
    ResetCoordinates()
    
    AddPathSegments("M 40 20 L 120 20 L 120 60 L 200 60 L 200 100 L 280 100 L 280 140 L 360 140 L 360 180")
    VectorSourceColor(RGBA(255, 0, 0, 255))
    StrokePath(5, #PB_Path_RoundCorner)
    
    MovePathCursor(10, 30)
    RotateCoordinates(10, 30, 45)
    DrawVectorText("Red Line")
    
    ;Part 2
    ResetCoordinates()
    
    TranslateCoordinates(50, 50)      
    
    AddPathSegments("M 40 20 L 120 20 L 120 60 L 200 60 L 200 100 L 280 100 L 280 140 L 360 140 L 360 180")
    VectorSourceColor(RGBA(0, 0, 255, 255))
    StrokePath(5, #PB_Path_RoundCorner)
    
    MovePathCursor(10, 30)
    RotateCoordinates(10, 30, 45)
    DrawVectorText("Blue Line")
    
    ; Part 3
    ResetCoordinates()
    
    AddPathCircle(80, 80, 50, 0, 45)
    VectorSourceColor(RGBA(255, 0, 0, 255))
    StrokePath(5, #PB_Path_RoundCorner)
    
    AddPathCircle(80, 80, 50, 45, 90)
    VectorSourceColor(RGBA(0, 0, 255, 255))
    StrokePath(5, #PB_Path_RoundCorner)
    
    ; Part 4
    ResetCoordinates()
    
    VectorSourceColor(RGBA(64, 64, 64, 255))
    For i = 0 To 260 Step 20
      MovePathCursor(420, i + 20)
      DrawVectorText(Str(i))
    Next
    
    EndFlipCoordinates()
    
    StopVectorDrawing()
  EndIf
  
  Repeat
    Define Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
EndIf
[/size]
Last edited by mk-soft on Sat Nov 09, 2019 12:25 pm, edited 7 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vector Drawing Change coordinates system

Post by IdeasVacuum »

Thanks for all the responses guys, I will run some tests to see what works best with my data - which is always only lines, no text etc.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
mk-soft
Always Here
Always Here
Posts: 5404
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Vector Drawing Change coordinates system

Post by mk-soft »

I once extended the macros so that you can switch between BeginFlip and... and EndFlip... can also perform a ResetCoordinates. :wink:

P.S. DrawVectorText works now too :wink:

P.P.S. Update example :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vector Drawing Change coordinates system

Post by IdeasVacuum »

... It's just not working for me. The data arrives as pairs of points (the line end points), in no particular order. It would be great if there was a draw line function, I can get my head round that :mrgreen:

Simple Example
In PB coordinates, the Origin Point (near paper bottom left corner) must be @ X200 Y800

The line points, in World coordinates, where +X axis at the Origin is left, +Y axis is Up and Origin Point is X0, Y0
(@ The Paper Origin):

Line01 Pt01 101.1176, 0.0000 Pt02 756.6081, 0.0000
Line02 Pt01 739.8827, 106.6284 Pt02 10.0000, 167.9937
Line03 Pt01 10.0000, 167.9937 Pt02 101.1176, 0.0000
Line04 Pt01 739.8827, 106.6284 Pt02 756.6081, 0.0000

I think the 2D Drawing Lib, or GDI+, might be an easier way to do this.

What I would really like to do is specify the coordinate system, that would make everything much easier.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Vector Drawing Change coordinates system

Post by IdeasVacuum »

Well, I have found it's much easier if:

1) Use TranslateCoordinates() to set the Origin @ paper bottom left
2) Simply invert the Y values.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4663
Joined: Sun Apr 12, 2009 6:27 am

Re: Vector Drawing Change coordinates system

Post by RASHAD »

Hi IdeasVacuum

Code: Select all

Procedure lline(x1,y1,x2,y2)  
  ResetCoordinates()
  FlipCoordinatesY(90)
  MovePathCursor(x1,y1)
  AddPathLine(x2,y2)
EndProcedure
  
  If OpenWindow(0, 0, 0, 800, 200, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 0, 0, 800, 200)
    ;Line01 Pt01 101.1176, 0.0000 Pt02 756.6081, 0.0000
    ;Line02 Pt01 739.8827, 106.6284 Pt02 10.0000, 167.9937
    ;Line03 Pt01 10.0000, 167.9937 Pt02 101.1176, 0.0000
    ;Line04 Pt01 739.8827, 106.6284 Pt02 756.6081, 0.0000
    If StartVectorDrawing(CanvasVectorOutput(0))      
      lline(101,0,756,0)
      lline(739,106,10,167)
      lline(10,167,101,0)
      lline(739,106,756,0)      
      VectorSourceColor(RGBA(255, 0, 0, 255))
      StrokePath(1)
    
      StopVectorDrawing()
    EndIf
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
  EndIf

Egypt my love
Marc56us
Addict
Addict
Posts: 1479
Joined: Sat Feb 08, 2014 3:26 pm

Re: Vector Drawing Change coordinates system

Post by Marc56us »

Version with subtraction of coordinates :wink:

:!: (Save file in same Dir as data.txt before run)

Code: Select all

; Drawing from CAD file

EnableExplicit

Enumeration 
    #hFile
    #Win
    #Canvas
EndEnumeration

Structure Type_Line
    x1.l
    y1.l
    x2.l
    y2.l
EndStructure
NewList vLine.Type_Line()

Define Data_File$ = "Datas.txt" ; (see content sample below)

; Line01 Pt01 101.1176, 0.0000 Pt02 756.6081, 0.0000
; Line02 Pt01 739.8827, 106.6284 Pt02 10.0000, 167.9937
; Line03 Pt01 10.0000, 167.9937 Pt02 101.1176, 0.0000
; Line04 Pt01 739.8827, 106.6284 Pt02 756.6081, 0.0000

OpenWindow(#Win, 0, 0, 800, 300, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(#Canvas, 10, 10, WindowWidth(#Win) - 20, WindowHeight(#Win) - 20)
Define New_Y = GadgetHeight(#Canvas) 

; --- Load datas from file
If Not OpenFile(#hFile, Data_File$)
    Debug "Can't Load Datas"
    End
EndIf
Debug "Reading..."
While Not Eof(#hFile)
    AddElement(vLine()) 
    Define Tmp_Line$ = ReadString(#hFile)
    With vLine()
        \x1 =         Val(StringField(Tmp_Line$, 3, " "))
        \y1 = New_Y - Val(StringField(Tmp_Line$, 4, " "))
        \x2 =         Val(StringField(Tmp_Line$, 6, " "))
        \y2 = New_Y - Val(StringField(Tmp_Line$, 7, " "))
    EndWith
Wend
Debug "Read Done."
CloseFile(#hFile)

If StartVectorDrawing(CanvasVectorOutput(#Canvas))      
    With vLine()
        ForEach vLine()
            MovePathCursor(\x1, \y1)
            AddPathLine   (\x2, \y2)
        Next
    EndWith
    VectorSourceColor(RGBA(0, 0, 255, 255))
    StrokePath(1)
    StopVectorDrawing()
EndIf

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Data.txt

Code: Select all

Line01 Pt01 101.1176, 0.0000 Pt02 756.6081, 0.0000
Line02 Pt01 739.8827, 106.6284 Pt02 10.0000, 167.9937
Line03 Pt01 10.0000, 167.9937 Pt02 101.1176, 0.0000
Line04 Pt01 739.8827, 106.6284 Pt02 756.6081, 0.0000
It remains to test what will run fastest with a lot of data ?
Post Reply