Visio Guy

Visio Discussions => Programming & Code => Topic started by: bsculley on August 18, 2016, 12:48:11 PM

Title: Convert SVG arc to Visio and back
Post by: bsculley on August 18, 2016, 12:48:11 PM
I am developing a Visio add-in in C#.  The purpose of the add-in is to allow an SVG file to be edited in Visio, but not using Visio's SVG import/export.  The SVG file contains private namespace data and some other specialized stuff that must be preserved, so the normal SVG open/save process cannot be used.  The add-in reads the SVG as XML and creates the Visio shapes programmatically, then reverses the process when the file is saved.

The problem I am encountering with this is that I can't figure out how to convert elliptical arcs.  The SVG format uses a starting and ending point with two radii to specify the arc, while Visio uses a different basis for defining the arc.  I know the equations to convert back and forth exist because the SVG is rendered correctly if I just open the file using Visio, but I have searched extensively and can't find anything that addresses my question, "how can I convert an SVG path arc to Visio and back again?"

Anyone out there familiar with Visio internals (or very good with geometry) that can provide the necessary equations?

Thanks
Bob
Title: Re: Convert SVG arc to Visio and back
Post by: vojo on August 18, 2016, 01:37:16 PM
This is really about translating center points to major/minor axis.

Perhaps these might help to understand how to:
Top is regular arc (right click)
bottom is elliptical arc (right click)

Then you can look at the shape sheet for conversion approach.
Title: Re: Convert SVG arc to Visio and back
Post by: bsculley on August 19, 2016, 03:46:41 PM
Thanks, I think I understand the concept, but I am still struggling with the execution.

Here is the SVG path I'm dealing with:  <path d="M12 19 A6 6 236.1413 0 0 5 30" />
This decodes as "move to x=12, y=19", "arc with radii 6,6 to x=5, y=30"  The parameters between "6 6" and "5 30" are not relevant to this exercise.

Here is the geometry that Visio generates for this shape when it opens the SVG file:





NameXYABCD
RelMoveTo1.00001.0000
RelEllipticalArcTo0.22220.00000.00000.81820.00001.0000

What I would really like is an explanation (preferably with examples) of how to get from point A to point B.  Sorry, but my math skills are not up to the task.

Thanks,
Bob
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on August 20, 2016, 10:57:26 AM
I have a shape of elliptical arc.
I hope this may help you.
Title: Re: Convert SVG arc to Visio and back
Post by: bsculley on August 22, 2016, 01:47:52 PM
Hello, and thank you.  I appreciate your efforts. 

I can see the relationships at work here, but what I am lacking are the specific calculations required to implement the transformation that I need, which is to represent an SVG path arc in Visio, and then reverse the process.

If anyone has actual code that can accomplish this I would be grateful if you could share it.

Bob
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on August 22, 2016, 02:13:12 PM
I am sorry I cannot understand what do you mean.
Title: Re: Convert SVG arc to Visio and back
Post by: Yacine on August 22, 2016, 04:40:47 PM
@Bob, with June you've certainly met the best possible specialist to solve your issue.
The problem is, we're all very Visio focused here at the visguy forum, so if YOU could provide the formulas to describe a SVG arc, then June will certainly find a way to translate it back and forth betwenn Visio and SVG.

My 2 cents, Y.
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on August 22, 2016, 11:38:19 PM
I think Visio can open SVG file.
The following is a simple test.
1. Insert a simple SVG file that contain an elliptical arc only that is made with Visio and saved as SVG file.
2. Ungroup the inserted elliptical arc 3 times, and get the Visio alliptical arc.
3. you can edit directly on the drawing page, or on shapesheet.

You can make a macro of  this proccess using macro recorder.
Title: Re: Convert SVG arc to Visio and back
Post by: Yacine on August 23, 2016, 05:42:15 AM
Bob is looking for formulas to convert by code Visio arcs into SVG and back. Description of SVG arc: https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands (https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands)
Title: Re: Convert SVG arc to Visio and back
Post by: bsculley on August 23, 2016, 08:06:49 PM
Yes!  Thank you Yacine.  I guess I wasn't being clear enough.

I need some help with the actual coding of the transformations using .Net 4.5 and C#.

Bob
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on August 23, 2016, 08:20:57 PM
There are already the converters in the web.
Please search in the web with the keywords like svg2vsd and vsd2svg.
It seems here you can download the source code.
http://dia-installer.de/vsd2svg/index.html.en
I think Visio includes sub program like these.
Title: Re: Convert SVG arc to Visio and back
Post by: bsculley on August 24, 2016, 07:48:58 PM
Thank you everyone for your patience.  I have located the code to convert a Visio elliptical arc to SVG (VSD2SVG).

Unfortunately, there is no reciprocal function that I can find.  I have searched SVG2VSD and all similar and related ideas, but with no luck.

I would appreciate any help anyone can provide on the conversion of an SVG path arc to a Visio EllipticalArcTo.  Is the Visio source open?  If it is I couldn't find it. 

I'm sure the equations are there since Visio can open an SVG file and render the arcs correctly.  As I mentioned at the beginning, I can't use the native Visio capability because there is private namespace material in the SVG file.

Bob
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on August 24, 2016, 11:45:36 PM
Quote
I am developing a Visio add-in in C#.
Why don't you use many powerful tools in Visio such as Visio mehods, properties, etc. in your add-in in your c#?
It might be much easier than you develop your own unique codes.
Title: Re: Convert SVG arc to Visio and back
Post by: bsculley on August 25, 2016, 04:26:52 PM
Hi Junichi,

A good suggestion.  Presented with an SVG arc path (M from-x, from-y A rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, to-x, to-y) what Visio tool(s) should I apply to create a corresponding shape?

Thanks again,
Bob
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on August 25, 2016, 07:49:13 PM
Quote
I think Visio can open SVG file.
The following is a simple test.
1. Insert a simple SVG file that contain an elliptical arc only that is made with Visio and saved as SVG file.
2. Ungroup the inserted elliptical arc 3 times, and get the Visio alliptical arc.
3. you can edit directly on the drawing page, or on shapesheet.

You can make a macro of  this proccess using macro recorder.

I think Visio is one of the best converter.
Title: Re: Convert SVG arc to Visio and back
Post by: wapperdude on August 26, 2016, 02:04:04 AM
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



Title: Re: Convert SVG arc to Visio and back
Post by: Nikolay on August 26, 2016, 06:11:44 AM
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 :)
Title: Re: Convert SVG arc to Visio and back
Post by: wapperdude on August 26, 2016, 06:33:59 AM
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
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on August 30, 2016, 02:54:03 AM
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
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on September 16, 2016, 12:39:50 AM
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.
Title: Re: Convert SVG arc to Visio and back
Post by: Yacine on September 16, 2016, 06:10:49 AM
Cool. In some years, this will be part of Junichi's legacy.
I wonder if I should buy it right now.
;D
Title: Re: Convert SVG arc to Visio and back
Post by: vojo on September 16, 2016, 02:47:51 PM
hmmm....looks remarkably similar to Einstein field equations.....hmmm

June...nice piece of work
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on September 20, 2016, 08:41:51 AM
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.
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on September 20, 2016, 11:22:31 PM
Revision:
Step 4 was blank, and added "Multiply by 0.3528 (mm) to Point Data."
Above drawing was replaced.
Title: Re: Convert SVG arc to Visio and back
Post by: Nikolay on September 21, 2016, 10:30:58 PM
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
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on October 06, 2016, 12:25:15 PM
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
Title: Re: Convert SVG arc to Visio and back
Post by: JuneTheSecond on October 21, 2016, 06:14:43 AM
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