Interpreting compressed SVG path command syntax - svg

I'm working with compressed SVG path data which has been output from SVGO, and I can't understand one part of a relative line-to command. The path itself looks like this (it's a triangle, and it displays correctly):
<path d="M2107.49 3283.96l70.68 81.44 28.54-81.69-99.22.25z"/>
Pulling apart the d attribute into commands, we get:
M: (Start coords) 2107.49 3283.96
l: (Relative line to coords) 70.68 81.44 28.54-81.69-99.22.25
z (close)
The piece I don't understand is the last 'pair' of the line-to commands: From what I understand, we should have 3 pairs of coordinates, which are either separated by a space 70.68 81.44, or where negative, no space: 28.54-81.69 = 28.54, -81.69. But what's going on in that last 'pair'? Does -99.22.25 represent -99.2 and 2.25? How would I know how to split that?
SVGO is trying to squeeze every last byte out of its compression, so it's possibly taking advantage of some implied parsing rule I can't find a reference to. Does anyone know how to deal with that last pair?

Per the BNF in the SVG specification
...
Similarly, for the string "M 0.6.5", the first coordinate of the "moveto" consumes the characters "0.6" and stops upon encountering the second decimal point because the production of a "coordinate" only allows one decimal point. The result is that the first coordinate will be "0.6" and the second coordinate will be ".5".
So -99.22.25 is -99.22 followed by .25

Related

Calculate CV2 Homography by points and line

I have a list of points in the field (like upper_goal_point/ left_upper_outer_corner, etc.
I know their corresponding coordinates in destination image - so I can calculate the homography:
h, status = cv2.findHomography(pts_src, pts_dst)
I also have blue points in the upper corner line (look at image above), which I only know that their destination's y coordinates are 0 (because they are in the upper line), but I don't know where exactly they lay in that line.
Can I use those blue points in order to improve the homography?
P.S.
You can see that the upper corner line in the homography is not horizontal line, it's diagonal, which of course is not correct:
Actually it possible to use line correspondence in find homography.
https://www.researchgate.net/publication/220845575_Combining_Line_and_Point_Correspondences_for_Homography_Estimation
Several years ago we implement this approach in one project. During simplification all math we come up with simple trick. We transform every line a*x + b*y + c = 0 to point (a/c, b/c)
// *** Don't copy paste this code, read below! ***//
Point2f convertPointsToHomogeneousLine(Point2f p1, Point2f p2) {
Point3f p1h(p1.x, p1.y, 1);
Point3f p2h(p2.x, p2.y, 1);
Point3f lineHomo(p1h.y*p2h.z - p1h.z*p2h.y,
p1h.z*p2h.x - p1h.x*p2h.z,
p1h.x*p2h.y - p1h.y*p2h.x);
Point2f lineHomoNorm(lineHomo.x / lineHomo.z,
lineHomo.y / lineHomo.z);
return lineHomoNorm;
}
And pass this points inside. As I remember I also dig inside OpenCV implementation of findHomography and insert this lines somewhere inside to solve step. Inside OpenCV there some normalization applied to points before pass to solve step. So you need to skip this step for this kind of points.
We do not use it in production. User need to calibrate camera manually by providing lines and points on the image and in meter system. It has too complicated interface and bad stability. But in your case I think it can work better. If you will automatically find lines and correspondence.
P.S. Please note that in paper they use some normalization technique.
It will improve stability. We faced with stability problem, do not
solved it in our journey.

Finding the filled side of an SVG path

I am creating an animation the camera moves along the path from M to z (closed path). As the camera moves, I need to know which side is inside the closed path.
Since the inside of a path is formed by clockwise move (in the default fill-rule of nonzero), I assumed the inside is always on the right side of the path.
However, I encountered cases where the filled area is on the left side of the path.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26.986 26.986"><path d="M.614 2.145V24.84C.614 26.028 1.575 26.986 2.759 26.986H24.226C25.41 26.986 26.372 26.027 26.372 24.84V2.145C26.372 .963 25.409 0 24.225 0H2.759C1.575 0 .614 .963 .614 2.145zM8.778 20.82C8.778 22.353 7.534 23.599 6.001 23.599C4.466 23.599 3.224 22.353 3.224 20.82C3.224 19.289 4.466 18.043 6.001 18.043C7.534 18.043 8.778 19.289 8.778 20.82zM23.696 5.596C23.696 7.131 22.45 8.375 20.917 8.375C19.386 8.375 18.142 7.131 18.142 5.596C18.142 4.063 19.386 2.819 20.917 2.819C22.45 2.818 23.696 4.062 23.696 5.596z"/>
<circle cx="0.614" cy="2.145" r="2" fill="red"/>
<path d="M.614 2.145V24.84" stroke="blue" />
</svg>
I know we can check if a typical point is inside the closed path by polygon methods.
I wonder if there is a simpler method for finding the inside of a closed path when moving from M to z?
I just need to know when moving from M to z, the inside of the closed path is on the right or left side of the camera.
The first assumption
...the inside of a path is formed by clockwise move...
is only true if the path is non-overlapping and does not define a hole. If your path never crosses itself and has no holes, the inside will always be to your right assuming that you are following the path in a clockwise move. However, in your example the movement from the red dot through the blue line is counterclockwise.
A general solution to this problem would be long and laborious. However, depending on the design of your script, it might be much simpler. If you are always drawing your figure clockwise (as in your example), the inside is to your rigth when you follow the same order of points, and to your left if you are reversing the order of your points. Notice that in your example you are reversing the order of points - the path is closed from the last point (z) to the first (M).
If not, this procedure should work:
Start with the point where the camera is and the vector showing where it points.
Rotate this vector by any angle higher than 0 and lower than π (that would be to the left).
Follow the vector from the point of the camera and find how many times it intersects with your path (current segment excluded). If this number is even, the inside is to the right of the camera. If the number is odd, it is to the left.
This is feasible, but by no means trivial. For the third step, you might use the bounding box of your path as "infinity". To exclude the current segment, your procedure to find the intersection of two segments should return false if one of the extremes of one segment belongs to the other segment. It should also return false if both segments are parallel. You would also need to decide the behavior you want in special points, such as vertices.

What do the 'M', 'c' and 'z' mean in SVG paths?

http://paperjs.org/examples/
I'm trying to create a custom path with Chain, and I see that Tadpoles has a predefined heart-shaped path, so I'm trying to copy it but I don't understand a few parts of it.
var heartPath = new Path('M514.69629,624.70313c-7.10205,-27.02441 -17.2373,-52.39453 -30.40576,-76.10059c-13.17383,-23.70703 -38.65137,-60.52246 -76.44434,-110.45801c-27.71631,-36.64355 -44.78174,-59.89355 -51.19189,-69.74414c-10.5376,-16.02979 -18.15527,-30.74951 -22.84717,-44.14893c-4.69727,-13.39893 -7.04297,-26.97021 -7.04297,-40.71289c0,-25.42432 8.47119,-46.72559 25.42383,-63.90381c16.94775,-17.17871 37.90527,-25.76758 62.87354,-25.76758c25.19287,0 47.06885,8.93262 65.62158,26.79834c13.96826,13.28662 25.30615,33.10059 34.01318,59.4375c7.55859,-25.88037 18.20898,-45.57666 31.95215,-59.09424c19.00879,-18.32178 40.99707,-27.48535 65.96484,-27.48535c24.7373,0 45.69531,8.53564 62.87305,25.5957c17.17871,17.06592 25.76855,37.39551 25.76855,60.98389c0,20.61377 -5.04102,42.08691 -15.11719,64.41895c-10.08203,22.33203 -29.54687,51.59521 -58.40723,87.78271c-37.56738,47.41211 -64.93457,86.35352 -82.11328,116.8125c-13.51758,24.0498 -23.82422,49.24902 -30.9209,75.58594z');
I don't understand what the M at the start of the path means, or the c in some of the values or z at the end of the path. I tried to find info about it in their docs or Google it but I can't find what I want because single letters make searching tough.
I tried to remove the M at the start and the Tadpoles stopped moving, so I assume M potentially means 'moving'? Removing the c alters the shape of the heart, but removing the z doesn't seem to change anything.
M: Move to
The command "Move To" or M, which was described above. It takes two parameters, a coordinate ' x ' and coordinate ' y ' to move to. If your cursor already was somewhere on the page, no line is drawn to connect the two places. The "Move To" command appears at the beginning of paths to specify where the drawing should start
z: Close Path
This command draws a straight line from the current position back to the first point of the path. It is often placed at the end of a path node, although not always. There is no difference between the uppercase and lowercase command.
c: Bezier Curves
The cubic curve, C, is the slightly more complex curve. Cubic Beziers take in two control points for each point. Therefore, to create a cubic Bezier, you need to specify three sets of coordinates.
source: https://developer.mozilla.org/en/docs/Web/SVG/Tutorial/Paths
-EDIT-
You can visit https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d for a full reference to all the possible commands and their usage.
The constructor you are invoking is this:
Path(, pathData)
Where pathData is described as:
the SVG path-data that describes the geometry of this path
The documentation you should read is the one of SVG.
As #GerardoFurtado mentioned in the comments, here is a read that could be of interest for you.

Paraview bug when displaying vtkUniformGrid?

I am displaying a vtkUNiformGrid in Paraview, which contains (besides other things) 3-component flow vector in each point. When I display the dataset with volume rendering, it displays just fines. However, when I add Arrow glyph to the very same data, they do show the same data but elsewhere, smaller and in multiple copies (9 in number). Perhaps an images shows better what I mean:
I am a bit at loss as to where to look. Did I screw something up? Other ideas?
To help you debug, open a 2nd layout window and select Spreadsheet View, and look at the source on which you are applying the glyph filter. Is the vector data that you're trying to plot under PointData? Then check in the glyph filter properties that the Vectors drop down box indicates the array that you're trying to plot.
Just for the record, the cause was actually writing data into the vtkDoubleArray in a wrong way -- the array has 3 components and the indices were actually 1/3 of what they should have been, with x/y/z values interspersed (that gives the 3x3 pattern in the lower third, as I realized); I was assuming the components were stored contiguously, which is apparently not the case.
The old code was something like this:
auto flow=vtkSmartPointer<vtkDoubleArray>::New();
flow->SetNumberOfComponents(3);
auto grid=vtkSmartPointer<vtkUniformGrid>::New();
grid->SetDimensions(...);
grid->GetPointData()->AddArray(flow);
for(int i:{0,1,2}) flow->FillComponent(i,0);
for(ijk: ... /* traverses the grid, each point potentially more than once */ ){
vtkIdType dataId=grid->ComputePointId(ijk);
// XXX: this is what caused troubles:
double* f0=flow->GetPointer(dataId);
f[0]+=dx;
f[1]+=dy;
f[2]+=dz;
}
The correct version of the loop body is:
double f[3];
flow->GetTupleValue(dataId,f); // copy the data
f[0]+=dx;
f[1]+=dy;
f[2]+=dz;
flow->SetTupleValue(dataId,f);
Both scalar and vector datasets are now matching:

Placing "markers" in MathJax math expressions

Suppose I have some equation, say:
$$\underbrace{ \frac{a}{b} }_{c}$$
And, I want to get the location of the $c$ in the HTML/CSS/SVG output of MathJax.
Is there a way to do this? I.e. I'd like to do something like:
$$\underbrace{ \frac{a}{b} }_{c\invisiblemarkerXYZ}$$
then be able to do a query to get the DOM element corresponding with invisiblemarkerXYZ
Thanks!
EDIT this is what I want to do:
Equation 1 = $$\underbrace{\frac{a}{b}}{A}$$
Equation 2 = $$A = \sum_{i=1}^n i$$
Now, I want to draw a line (via SVG) of the two A's. Thus, I need some way to obtain the location of the MathJax elements.
You can use \cssId{XYZ}{c} to set the id="XYZ" on the element used for the c, and can then use document.getElementById("XYZ") to obtain that DOM element. But the output from MathJax's HTML-CSS and SVG processors is not designed to be manipulated after the fact. For example, in general you will not be able to get the dimensions of the element from the HTML-CSS output as the offsetHeight and offsetWidth may not be what you expect them to be. (The height is frequently set to 0, for example.)
Can you say something more about what you are trying to accomplish?

Resources