Closed TimotheAlbouy closed 10 months ago
So now, let's talk about how this feature could be implemented.
Currently, line("A", "B", mark: (end: ">", start: ">"))
resolves the "A"
and "B"
parameters of the line()
function as the "A.default"
and "B.default"
anchors, which respectively correspond to the centers of the circle and the rectangle. So this code would produce a line that goes from the center of the circle to the center of the rectangle, which is not what we want. This current behaviour of CeTZ could be redefined to implement the feature of this post.
However, this is easier said than done, because in the current codebase, "A"
and "B"
get resolved independently of each other, but we can see that, to resolve "A"
into a coordinate, we need to know the position of the center of "B"
, and we can make a symmetric argument for "B"
. So we cannot resolve the different coordinates one by one, like what is done in the coordinate.typ
file right now.
So we could add a new function in the coordinate.typ
file, for example called resolve-element-line-intersect()
, that would define a new resolution rule resolving the coordinates of the point at the edge of element "A"
based on the direction of the other point (the center of element "B"
in my example). We would then repeat the operation on the second point "B"
. This function would take in parameters the name of the first element for which we must touch the edge, and the second coordinate towards which the line is oriented. This second coordinate could be expressed in any format that is currently resolvable in the coordinate.typ
file. This way, it would be possible to have "well-centered" lines between an element name (e.g., "A"
) and a classic coordinate (e.g., (2,3)
) or an anchor (e.g., "B.bottom"
) for example, like what is already possible in TikZ. However, to get the simple line("A", "B")
syntax that I gave above, I think that it's not possible to do everything inside the resolution rules, and some logic specific to the "well-centered line" rule will have to be added to the line()
function.
Next, we have to work out how this resolve-element-line-intersect()
function would work. The most natural way to implement this feature may be to leverage the intersections()
function. However, I think that the current issues with the intersections()
function (and especially this one) will have to be fixed first.
I will try to write the resolve-element-line-intersect()
function later here.
line(..)
now accepts element names as first and/or last coordinates to calculate border intersections.
Currently, there is no simple way to draw a "well-centered line" between 2 elements in CeTZ.
I call a line between two elements "well-centered" if it follows the same path as the infinite line that passes through the centers of both elements, but it just touches the edges of the 2 elements instead. I know that this may not be very clear, so this is the kind of things that I want to achieve (this was produced in TikZ):
The solution should also be element- and position-agnostic, so no cheating like for instance assuming that the elements are circles of a given radius, or assuming their position and inferring a given line angle.
Doing this in TikZ is very easy:
So the solution in CeTZ should be as intuitive as the TikZ solution. Something like:
Such a feature could be very helpful for a variety of things, such as drawing pretty box-and-arrow diagrams. It could also be useful for the tree CeTZ library (see this other issue) to replicate the behaviour of the tree TikZ library (the lines between the elements are "well-centered", and not drawn between the
top
andbottom
anchors of the elements).See this Discord thread for more info.