Convert SVG arc to Visio and back

Started by bsculley, August 18, 2016, 12:48:11 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

wapperdude

I've not seen the conversion algorithm ever.  Doubt that it's available outside of the normal Visio svg file editing routine.  You may have to develop a different strategy. 

Wapperdude



Visio 2019 Pro

Nikolay

#16
SVG uses radiuses + angle approach to describe the elliptical arc (check "Arcs" section, it's like children's book with pictures - should explain properly how arc is described in svg):
https://developer.mozilla.org/en/docs/Web/SVG/Tutorial/Paths

Visio uses "point on the arc" approach to describe the arc (unfortunately I have not found reference with pictures)
https://msdn.microsoft.com/en-us/library/office/ff767078.aspx

Therefore to convert from SVG to Visio you'll need a point on the arc. Here is an example how to get one (check "marked as answer"):
http://math.stackexchange.com/questions/22064/calculating-a-point-that-lies-on-an-ellipse-given-an-angle

To convert back, you'll need to do the reverse..

Sorry I'm a bit too lazy for such exercises, but hope it may point you to the right direction and clarify what kind of formula you actually might need.
If you manage to find these formulas, feel free to post them here :)

wapperdude

Add to Nikolay's comment:

To uniquely specify the arc from one version to the other, I suspect you need 4 points:  both ends, and 2 points in between to make a unique solution.  Might need 1 more, but I think 4 is sufficient.

Too much math to grind thru, though.

Wapperdude
Visio 2019 Pro

JuneTheSecond

#18
I roughly imaged a conversion formulas from SVG to Visio shape sheet formulas.
But I am never sure they are right.
Even if they have any possiblity, many times of try and error will be necessary.
If you read carefully the source code of vsd2SVG, you might find lines corresponds to such conversion formulas. The lines will be for contrarily direction. but might give you any hint.

Visio vs SVG
x1=Xc (current point of SvG curve drawn last time or moveto.)
y1=Yc
x2=X1 (end point on SVG elliptical arc)
y2=Y1
A=X2 (point on SVG elliptical arc)
B=Y2
C=Calculated Relative Angle to base line
D=Xr/Yr or Yr/Xr
Best Regards,

Junichi Yoda
http://june.minibird.jp/

JuneTheSecond

#19
Here is a document that may help to calculate this issue.
http://stackoverflow.com/questions/197649/how-to-calculate-center-of-an-ellipse-by-two-points-and-radius-sizes
Tha way explained here is able to simplify the calculation.
But it does not applied to an angular ellipse.
So, I tried to expand the method.
Here is a hand written formulas on my notebook.
Best Regards,

Junichi Yoda
http://june.minibird.jp/

Yacine

Cool. In some years, this will be part of Junichi's legacy.
I wonder if I should buy it right now.
;D
Yacine

vojo

hmmm....looks remarkably similar to Einstein field equations.....hmmm

June...nice piece of work

JuneTheSecond

#22
Or it is more easy to convert with hand operation geometrically.
Here is an example drawing of the result of my experiment.
It has 2 pages steps, you may feel long, but not so long if you really operaye on drawaing.
I tried to convert these hand operations into pure mathematical VBA program, but for me it is too hard.
Best Regards,

Junichi Yoda
http://june.minibird.jp/

JuneTheSecond

#23
Revision:
Step 4 was blank, and added "Multiply by 0.3528 (mm) to Point Data."
Above drawing was replaced.
Best Regards,

Junichi Yoda
http://june.minibird.jp/

Nikolay

#24
It seems that the topic-starter hoped to get just the formula to transform SVG "elliptical path" to VSD "elliptical path" and not PHD in math transforms :)
Looks like we have lost him? :D

JuneTheSecond

#25
Here is an trial VBA macro.

Option Explicit

Sub ConvertSVGArcToVisioArc()
    Dim LAF As Long, SWF As Long 'Long arc flag and sweep flag as definrd in SVG path format.
    Dim cf As Double 'Number to convert length of SVG into Visio
    Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double ' Start point and end point of arc.
    Dim xm As Double, ym As Double 'Mid point of start and end point of ard.
    Dim athita As Double, thita As Double 'Angle of ellipse
    Dim x0 As Double, y0 As Double, xd As Double, yd As Double 'Dummy origin not center of ellipse
    Dim rx As Double, ry As Double 'Major and minor radius of ellipse
    Dim ratio As Double, shratio As Double 'Ratio to expand and shrink
    Dim x3 As Double, y3 As Double, x4 As Double, y4 As Double 'Starting & End points of arc after Expanding
    Dim x5 As Double, y5 As Double, x6 As Double, y6 As Double 'Centers of circle passing through start & end points of arc
    Dim x7 As Double, y7 As Double, x8 As Double, y8 As Double 'Mid points on arc
    Dim x9 As Double, y9 As Double, x10 As Double, y10 As Double 'Mid points on arc
    Dim len1 As Double, len2 As Double, len3 As Double, len4 As Double
    Dim xms As Double, yms As Double 'Selected mid point on arc at step 10
    Dim shp As Visio.Shape
    Dim xmss As Double, ymss As Double 'Mid points of selected mid point after shrink.
   
    LAF = 0
    SWF = 0
    cf = 0.3528
    xd = 0#
    yd = 20#
   
    x1 = 68.45
    y1 = 27.43
    x2 = 0#
    y2 = 9.09
    rx = 41.2537
    ry = 27.5024
    athita = -5#
   
       
'     Step 4 Convert SVG coordinete into Visio coordinate.
    x1 = xd + x1 * cf 'Starting Point of arc
    y1 = yd - y1 * cf
    x2 = xd + x2 * cf 'Ebd point of arc
    y2 = yd - y2 * cf
    rx = rx * cf
    ry = ry * cf
    x0 = x1
    y0 = y1
    thita = -athita * pi() / 180#

'    Step 7 & 9 Expand points along minor radius of ellipse.
    ratio = rx / ry   ' Greater than 1.0
    ExpandSp x1, y1, ratio, thita, x0, y0, x3, y3  ' Expand along minor radious by ratio
    ExpandSp x2, y2, ratio, thita, x0, y0, x4, y4  ' Expand along minor radious by ratio
   
'   Get Mid point of Start and end points of arc.
    xm = (x3 + x4) / 2#
    ym = (y3 + y4) / 2#

       
'    Step 10 : Get center of ciecles.
    CenterOfCircle x3, y3, x4, y4, rx, x5, y5, x6, y6
       
'   Step Extra 1 : Get Mid point2 on arcs.
    MidPointsOnCircle x3, y3, x4, y4, rx, x5, y5, x7, y7, x8, y8
    MidPointsOnCircle x3, y3, x4, y4, rx, x6, y6, x9, y9, x10, y10
   
'   Step 10 : Select a Mid point on arc reffering to 2 factors in SVG, Large Arc Flag and Sweep Flag.
    SellectMidPointOnArc LAF, SWF, rx, xm, ym, x3, y3, x4, y4, x5, y5, x7, y7, x8, y8, x9, y9, x10, y10, xms, yms
   
'    Step 12 & 13 Shrink selected mid point along minor radius of ellipse.
    shratio = ry / rx   ' Les than 1.0
    ExpandSp xms, yms, shratio, thita, x0, y0, xmss, ymss  ' Expand along minor radious by ratio
   
'    Step 14 : Draw Elliptical arc
    DrawArcMm x1, y1, x2, y2, xmss, ymss, athita, ratio
   
End Sub



Other sub routines are in sample drawing.
Hereis a short vide to show the speed of macro.
https://youtu.be/RJ-2sHYIZbk
Best Regards,

Junichi Yoda
http://june.minibird.jp/

JuneTheSecond

#26
Here is another macro using trigonometric method.
Please enjoy.

All necessary sub routines are in the attached drawing.


Option Explicit

Sub ConvertSVGArcToVisioArc()
    Dim LAF As Long, SWF As Long 'Long arc flag and sweep flag as definrd in SVG path format.
    Dim cf As Double 'Number to convert length of SVG into Visio
    Dim x1 As Double, y1 As Double, x2 As Double, y2 As Double ' Start point and end point of arc.
    Dim xm As Double, ym As Double 'Mid point of start and end point of ard.
    Dim athita As Double, thita As Double 'Angle of ellipse
    Dim x0 As Double, y0 As Double, xd As Double, yd As Double 'Dummy origin not center of ellipse
    Dim rx As Double, ry As Double 'Major and minor radius of ellipse
    Dim x3 As Double, y3 As Double, x4 As Double, y4 As Double 'Starting & End points of arc after Expanding
    Dim x5 As Double, y5 As Double, x6 As Double, y6 As Double 'Centers of circle passing through start & end points of arc
    Dim x7 As Double, y7 As Double, x8 As Double, y8 As Double 'Mid points on arc
    Dim x9 As Double, y9 As Double, x10 As Double, y10 As Double 'Mid points on arc
    Dim shp As Visio.Shape
    Dim xmss As Double, ymss As Double 'Mid points of selected mid point after shrink.
   
    Dim th1 As Double
    Dim thH1 As Double, thI1 As Double
   
    Dim eps As Double
    eps = 0.001
   
    cf = 0.3528
    xd = 0#
    yd = 20#
   
    x1 = 99.21
    y1 = 57.5
   
    rx = 86.0239
    ry = 43.012

    athita = -175.26
   
    LAF = 0
    SWF = 0

    x2 = 0
    y2 = 0.81
   
       
'     Convert SVG coordinete into Visio coordinate.
    x1 = xd + x1 * cf 'Starting Point of arc
    y1 = yd - y1 * cf
    x2 = xd + x2 * cf 'Ebd point of arc
    y2 = yd - y2 * cf
    rx = rx * cf
    ry = ry * cf
    x0 = x1
    y0 = y1
   
'     Get mid point on the line start and end point of arc.
    xm = (x1 + x2) / 2#
    ym = (y1 + y2) / 2#
   
    thita = -athita * pi / 180#
   
'     Get large thita from my formula.
    thH1 = Atn((ry / rx) * ((x1 - x2) * Cos(thita) + (y1 - y2) * Sin(thita)) / _
                       ((x1 - x2) * Sin(thita) - (y1 - y2) * Cos(thita)))
'    thH2 = thH1 + pi
   
    thI1 = ASin(-(x1 - x2) / (2# * (rx * Cos(thita) * Sin(thH1) + ry * Sin(thita) * Cos(thH1))))
   
'     Get small thita from definitions.
    th1 = thH1 + thI1
   
'     Get center points of ellipse
    x5 = x1 - rx * Cos(th1) * Cos(thita) + ry * Sin(th1) * Sin(thita)
    y5 = y1 - rx * Cos(th1) * Sin(thita) - ry * Sin(th1) * Cos(thita)
   
    x6 = 2# * xm - x5
    y6 = 2# * ym - y5
   
'     Get middle points on arcs from my formula.
    x7 = x5 + rx * Cos(thH1) * Cos(thita) - ry * Sin(thH1) * Sin(thita)
    y7 = y5 + rx * Cos(thH1) * Sin(thita) + ry * Sin(thH1) * Cos(thita)
   
    x8 = 2# * xm - x7
    y8 = 2# * ym - y7
   
    x9 = x6 + rx * Cos(thH1) * Cos(thita) - ry * Sin(thH1) * Sin(thita)
    y9 = y6 + rx * Cos(thH1) * Sin(thita) + ry * Sin(thH1) * Cos(thita)
   
    x10 = 2# * xm - x9
    y10 = 2# * ym - y9
   
    SellectMidPointOnArc LAF, SWF, rx, xm, ym, x1, y1, x2, y2, x5, y5, x7, y7, x8, y8, x9, y9, x10, y10, xmss, ymss

    DrawArcMm x1, y1, x2, y2, xmss, ymss, athita, rx / ry
   
End Sub

Best Regards,

Junichi Yoda
http://june.minibird.jp/