Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent intersections #25

Closed
Volker-Weissmann opened this issue Mar 24, 2021 · 3 comments
Closed

Inconsistent intersections #25

Volker-Weissmann opened this issue Mar 24, 2021 · 3 comments

Comments

@Volker-Weissmann
Copy link

Let's look at this code:

from pyx import *
from math import *

c = canvas.canvas()
angles = {"B": 0, "A": 2*pi/3, "C": 2*pi*2/3}

circles={}
for k,v in angles.items():
    circles[k] = path.circle(sin(v), cos(v), 1.7)
    c.stroke(circles[k])

def intersect(cp1, cp2):
    (int1), (int2) = cp1.intersect(cp2)
    arch1 = cp1.split(int1)[1]
    return arch1

c.stroke(intersect(circles["B"], circles["A"]), [color.rgb.red])
c.stroke(intersect(circles["C"], circles["B"]), [color.rgb.green])
c.stroke(intersect(circles["A"], circles["C"]), [color.rgb.blue])

c.writePDFfile()

As one might expect, it produces this figure

But If I replace the last part with

c.stroke(intersect(circles["A"], circles["B"]), [color.rgb.red])
c.stroke(intersect(circles["B"], circles["C"]), [color.rgb.green])
c.stroke(intersect(circles["C"], circles["A"]), [color.rgb.blue])

the results looks like this.

The way the blue line looks is inconsistent with the rest.

@wobsta
Copy link
Contributor

wobsta commented Mar 25, 2021

PyX behaves very well defined given the fact, that circles are closed paths, but still have a begin and end point. It is the point to the right, but you may rotate it, like to the top like so path.circle(sin(v), cos(v), 1.7).transformed(trafo.rotate(90, sin(v), cos(v))). The intersect return values are ordered along the first path. Quoting from the split example of the gallery (https://nbviewer.jupyter.org/urls/sf.net/p/pyx/gallery/split/attachment/split.ipynb):

The first segment returned by the split method ends at the first splitting point, the second segment goes from the first splitting point to the second splitting point (and maybe this path element will thus have a different orientation than the original path). Finally, for an open path the last item in the list of returned segments will go from the last splitting point to the end of the path. However, for a closed path this last path item is prepended to the first segment returned by the split method. Thus for a closed path the first segment will always go from the last to the first splitting point.

Your code should probably return the shorter of the two paths created from the split method ...

@wobsta wobsta closed this as completed Mar 25, 2021
@Volker-Weissmann
Copy link
Author

Returning the shorter of two paths might we correct in this case, but is wrong in other cases.

IMHO, there should be a documented way how to get the intersecting area of two closed paths, e.g. for a venn diagram.

@wobsta
Copy link
Contributor

wobsta commented Mar 27, 2021

I am not quite sure whether it is the right format to discuss on a close issue, but I don't mind. In addition I am not familiar with venn diagrams.

Regarding the area of two intersecting closed paths, there clearly are several solutions:

from pyx import *

c = canvas.canvas()

def intersect(y, p1, p2):
    c1 = path.circle(0, y, 4)
    c2 = path.circle(3, y, 2)
    c.stroke(c1)
    c.stroke(c2)
    (int1), (int2) = c1.intersect(c2)
    c1segs = c1.split(int1)
    c2segs = c2.split(int2)
    c.fill(c1segs[p1] << c2segs[p2].reversed(), [color.rgb.red])

intersect(0, 0, 0)
intersect(-10, 1, 0)
intersect(-20, 0, 1)
intersect(-30, 1, 1)

c.writePDFfile()

intersects.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants