[Ipe-discuss] ipe features

Marc Glisse marc.glisse at normalesup.org
Wed Jan 25 18:06:28 CET 2006


On Wed, 25 Jan 2006, Jan Hlavacek wrote:

> The main problem with this is that IPE 6 does not snap to the intersections 
> of circles or splines, so the snapping is not going to help here.

It is actually not that hard to get some rough snapping done. The hardest 
point in my opinion is that there are some design decisions to make, and 
Otfried is the only one who can make them. The Intersects functions can 
only set the value of one IpeVector, so either this prototype should be 
modified so one can set a list of intersection points, or the said 
IpeVector should be initialized before a call to the function and the 
function should return the intersection point closest to this one. And in 
this second case it might still be interesting to modify the prototype to 
pass snapDist.

In the second case, one of the functions could be:

bool IpeArc::Intersects(const IpeLine &l, IpeVector & x) const
{
    IpeMatrix inv = iM.Inverse();
    IpeVector p = inv * l.iP;
    IpeVector q = inv * (l.iP + l.Dir());
    IpeLine l1 = IpeLine::Through(p, q);
    IpeVector a=l1.Dir().Orthogonal();
    IpeVector m;
    if(!IpeSegment(-a,a).Intersects(l1,m)) return false;
    IpeVector s=sqrt(1-m.SqLen())*l1.Dir();
    IpeVector v1=m+s;
    IpeVector v2=m-s;
    bool k1=true,k2=true;
    if (iAlpha != 0.0 || iBeta != 0.0) {
        k1=v1.Angle().LiesBetween(iAlpha,iBeta);
        k2=v2.Angle().LiesBetween(iAlpha,iBeta);
    }
    v1=iM*v1;
    v2=iM*v2;
    double d1=(v1-x).SqLen();
    double d2=(v2-x).SqLen();
    if(k1){
        if(k2){
            x=(d1<d2)?v1:v2;
            return true;
        }else{
            x=v1;
            return true;
        }
    }else{
        if(k2){
            x=v2;
            return true;
        }else{
            return false;
        }
    }
}

The code could be written more cleverly, but it seems to work. A similar
function can be used for segments (add a check that the point is between
the extremities).

The code for the intersection of 2 circles is more complicated so I did
not write it. But anyway I am not sure it is necessary, or even
desirable. Indeed, if I understand correctly, circles are replaced by
splines for the drawing, so it would be more accurate to compute the
intersections with those splines.

And to compute intersections with splines I used the very silly and
inefficient technique of replacing them by polylines (using the
Approximate function), which is good enough for me, but probably not for
everyone.

But then I had another issue. Polylines are considered as sets of
segments, so every vertex is also an intersection point. In this case it
is not that bad, but for splines this may introduce arbitrary extra
intersection points in uninteresting places (even without replacing
Bezier arcs with polylines).

Ok now, my random text generator is a bit tired...

Oh yes I just wanted to say, I usually am very happy with zooming,
clicking at the intersection, de-zooming, and using 'x' a lot, without
the snapping features, so I may not be the right person to talk about it.

-- 
Marc Glisse



More information about the Ipe-discuss mailing list