Placing "markers" in MathJax math expressions - mathjax

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?

Related

How to get global world coordinates of bone in Godot GDscript

I'm writing a program in Godot with GDscript that aims to change the position of multiple bones in an armature. The bone gets translated by a value calculated by the point I want the bone to move to minus the current position of the bone. translateValue = endPoint - currentPoint However, all values must be in world coordinates or global position for the code to work. Godot has various methods to retrieve the bone Transform in order to access the position such as : skeleton.get_bone_pose() , skeleton.get_bone_global_pose , skeleton.get_bone_rest . I tried using skeleton.get_bone_global_pose but it didn't give the global position and seemed to still be relative to something. There's also the to_global() method, but i'm not entirely sure what it does. Could someone explain the differences between these methods and how to get global position? Thanks!
I'll start with these methods:
get_bone_rest
get_bone_custom_pose
get_bone_pose
First of all, get_bone_rest gives you the default transform of the bone, relative to its parent bone. Then the other transform are stacked, in the above order.
Then we have:
get_bone_global_pose
This method gives you the final transform of the bone. And it is relative to the Skeleton. That is, this transform already includes the previously mentioned transforms, combined from parent to child bone.
Thus, converting its result to world space is a matter of composing the transform of the Skeleton:
$Skeleton.global_transform * $Skeleton.get_bone_global_pose(bone_index)
And we have:
get_bone_global_pose_no_override
As the name suggest get_bone_global_pose_no_override ignores any global pose override. That's right, you you can override the global pose. To do that, use set_bone_global_pose_override. See also clear_bones_global_pose_override. These are all, of course, relative to the Skeleton.
The method Spatial.to_global(vector3) is unrelated to the Skeleton. It transforms a vector from the local space of the node on which you call it, to world space. Which might also be useful:
$Skeleton.to_global($Skeleton.get_bone_global_pose(bone_index).origin)

Print a variable with index (eg. x_1)

i am trying to print variables with indices.
The goal is to write something like:
x_1 + x_2 = 3 + 1 = 4
The problem is, that variables just like x_1 does not show an index. It shows the underscore itself.
/* works fine */
print(x_1)$
x_1;
/* Does not work */
ostream: make_string_output_stream()$
printf(ostream, string(x_1))$
get_output_stream_string(ostream);
Output of the code above
Converting "x_1" into a string destroys the underscore, but you need a string for the method printf().
Are there workarounds for this?
What to do here probably depends somewhat on what goal you need to achieve with this. Can you say more about the larger goal you are working toward?
In order to generate output which has typesetting instructions in it, you can call the tex or tex1 function to generate TeX output. If that needs to be displayed in a web page, I believe you can make use of the MathJax Javascript library. Sorry, I don't know more about MathJax.
You should probably write x[1] instead of x_1. Displaying x_1 with a subscript 1 is a convenience -- the rest of Maxima doesn't know much about it.
EDIT: There is also an add-on package to output MathML; there might be two such packages, I would have to check. If MathML could help solve your problem, I will look into it.

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:

Raphael JS combine paths

I'm pretty new at SVG and Raphael, but I've been using Illustrator for many years, so I have some assumptions on how it works. I want to combine two paths which should return a single element.
I need to make a speech bubble, but it could be anything really. In this case I tried to make two rect, one with round corners and another square rect which was rotated. It looked alright, but when I tried to move the speech bubble, the rotated element moved in the wrong direction, because of the 45 degree rotation.
How can I compbine paths which I can later manipulate as if it was a single element/path?
Here you go DEMO
var paper = Raphael('canvas',400,400),
r1 = paper.rect(100,100,200,100).attr({fill:'black'}),
r2 = paper.rect(130,130,140,40,5).attr({fill:'white','stroke':'white'}),
r3 = paper.path("M200 170L240 170 220 180z").attr({fill:'white', 'stroke':'white'}),
p = paper.set(r1,r2,r3);
// the rest of the code is in the demo
Note, that it is easier to create triangle via path() and not worry about rotation.
Good Luck ;)
If you mean merging paths like using the Illustrator Pathfinder panel - turning several paths into one path (not a set of paths), merging overlap - I'm pretty sure there's no direct Raphael or SVG equivalent.
The closest thing is, creating a compound path (aka composite path) - the equivalent of cmd-8 or Object > Make Compound Path in Illustrator. This merges paths together into one path, but doesn't remove areas of overlap.
Basically, for a set paper.set( paper.path('M0,0 4,0 0,4z'),paper.path('M9,9 4,9 9,4z') );, an equivalent compound path would be paper.path('M0,0 4,0 0,4z M9,9 4,9 9,4z'); - just joining the path definitions into one, each starting with its own M.
Some differences to Raphael sets:
Less overhead (it's just one complex path, not several separate individual path elements)
Fewer surprises when you move it, sort it, etc:
Things applied to a Raphael set apply to each item in turn, not to the set as a unit - so for example toFront() changes the order within the set, and transforms centre around each item, like Illustrator's transform each, unless you give the transform static co-ordinates.
Things applied to a compound path, however, apply to the whole compound path as one unit.
It's not possible for subpaths of a compound path to have different attributes
Things like gradients apply once across the whole of the compound path, whereas with sets, there will be separate gradients on each separate path
JSBIN demo - compare the gradients, and see how the compound pair is just one path on the DOM.
Here's a simple plugin that adds the ability to take a set and create a compound path from it:
Raphael.st.compoundPath = function(){
var positions = [];
this.forEach( function( element ){
positions.push( element.compoundPath() );
});
return positions.join('');
}
Raphael.el.compoundPath = function(){
var path = this.attr('path');
return path ? Raphael.parsePathString( path ).join('') : '';
}
Then use it like this:
var someSet = paper.set(paper.path('M0,0 4,0 0,4z'),paper.path('M9,9 4,9 9,4z'));
var compPath = paper.path( someSet.compoundPath() );
someSet.remove(); // if you want to replace the set with a compound path
Note that it only combines paths in a set - if you need to combine other shapes with paths, you'll need a way to convert them into paths first.
First thing is that you could push your 2 elements into a Raphael set which you would later move with Element.transform(). This would let you apply the move handler once, and not twice.
Also for your issue, it is acually documented:
... There are also alternative “absolute” translation, rotation and
scale: T, R and S. They will not take previous transformation into
account. For example, ...T100,0 will always move element 100 px
horisontally, while ...t100,0 could move it vertically if there is r90
before. Just compare results of r90t100,0 and r90T100,0. ...

How to transform a path in svg so that it is parallel to its original location?

I have a path defined in SVG. I would like to make two copies of the path and translate them so that one sits parallel to the original on one side, and the other sits parallel on the other side. The idea is to end up with 3 paths, all parallel to each other and not overlapping.
I have tried simple translations such as transform="translate(10,10)" and transform="translate(-10,-10)" for the two paths, but in some paths they end up crossing each other which is not what I want.
Thanks.
Your answer should somewhat work as you've provided it. You might provide more concrete examples of your problem to evoke better solutions.
Your provided commands are going to move the item in two dimensions, not just one.
Also, keep in mind that SVG uses the upper left point as 0,0, and to the right/down are positive. Also check to make sure you're not getting tripped up by units.
If your original path has a bounding box of X,Y then the simplest way to make sure that the copied don't overlap is to translate by +X and -X, so:
translate(-X, 0)
and
translate(X, 0)
where you have computed the value of X and set it in the translate argument.
I'll give you some completely untested code written without looking at the SVG DOM spec. You can then test it and tweak it to get it to work.
First, get the bounding box of an element:
var box = mypath.getBBox();
Then clone the path twice (or make elements):
var rightCopy = mypath.cloneNode(true);
var bottomCopy = mypath.cloneNode(true);
Then transform each copy:
rightCopy.setAttribute("transform", "translate(" + box.width + ",0) " + rightCopy.getAttribute("transform"));
bottomCopy.setAttribute("transform", "translate(0," + box.height + ") " + bottomCopy.getAttribute("transform"));
The reason it looks messy is because the original path might have a transform already on it.
Then add those nodes back into the DOM:
mypath.parentNode.insertBefore(rightCopy, mypath);
mypath.parentNode.insertBefore(bottomCopy, mypath);

Resources