Variable Offset for each segment of a polyline-curve

Hey people,

I have some troubles getting my mind around an offset-thing.
I want to offset a polyline-curve with various distances for each segment.
I came up with 2 methods which work in different cases, but none of them works in all of the tested inputs.

If anybody has an advice how to go on, I would pretty happy to hear from u :slight_smile:

variableOffset.gh (16.6 KB)

greets
Mark

This is posted in the developer category, are you looking for code?

Hey David,

yes, I’m looking for code.
the attached definition contains two C#-Scripting Components which provides my attempts to solve the issue.

Should I post the code directly?

  private void RunScript(List<Curve> crv, List<double> offsets, ref object A)   {
    List<Curve> res = new List<Curve>();

    int i = 0;
    int ofN = offsets.Count;

    foreach (var c in crv){
      var of = offsets[i % ofN];
      var r = c.Offset(Plane.WorldXY, of, RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, CurveOffsetCornerStyle.None);

      var extend = Math.Abs(of * 10);
      foreach (var cr in r){
        var rr = cr.Extend(CurveEnd.Both, extend, CurveExtensionStyle.Arc);
        res.Add(rr);
      }
      i++;
    }

    const double intersection_tolerance = 0.001;
    const double overlap_tolerance = 0.0;

    var resN = res.Count;
    var resTrimA = new Interval[resN];
    var resTrimB = new Interval[resN];

    for (int k = 0; k < resN; k++){
      var events = Rhino.Geometry.Intersect.Intersection.CurveCurve(res[k], res[(k + 1) % resN], intersection_tolerance, overlap_tolerance);

      if (events.Count > 1){
        Print("I don't know what to do here");
        return;
      }
      else {
        var ccx_event = events[0];
        var aI = new Interval(res[k].Domain.T1, ccx_event.ParameterA);
        //aI.MakeIncreasing();
        resTrimA[k] = aI;

        var bI = new Interval(ccx_event.ParameterB, res[(k + 1) % resN].Domain.T0);
        //bI.MakeIncreasing();
        resTrimB[(k + 1) % resN] = bI;
      }
    }

    for (int k = 0; k < resN; k++){
      var aT = res[k].Trim(resTrimA[k]);
      aT = aT.Trim(resTrimB[k]);
      res[k] = aT;
    }
    A = res;
  }

greets

I was on an iPad, couldn’t open the files.

If you’re just dealing with polylines, then you can get away with a bunch of line-line intersections. You have to break your polyline into individual lines, move each line perpendicular to itself with the correct amount, then for each line find the intersection points with its immediate neighbours (line-line intersections assume infinitely long lines), and those two intersection points give you the new segment start and end. This won’t work well if your offset is so large that certain segments disappear entirely. Nor will it work for co-linear adjacent segments.

As said by David, here a solution with LineLine Intersection.
If polygon edge count is even an number of offsets uneven and the inverse, this will lead to problem. But whatever here a way of doing. Hope it helps.


variableOffset_LD.gh (12.5 KB)

Hi Laurent, what’s up? long time to talk.

See attached.

variableOffset_LaurentD_and_TheLord.gh (139.1 KB)

Use rather this:

variableOffset_LaurentD_and_TheLord_V1.3dm (113.7 KB)
variableOffset_LaurentD_and_TheLord_V1.gh (123.9 KB)

One of the problems with variable offsetting is the resulting loops when the sides overlap, so you have to use knot theory to get the principal offset polygon, this is my cheap attempt.
NON-CONVEX VARIABLE OFFSET.gh (10.1 KB)

Hi Antonio, are you 100% sure that the concave thing works 100%?

Staying for the monent on convex matters (mode shown: steady):

Nor the def posted works in all cases:

But this works. Actually … not … since it requires a big time (from 1 ms to 40 ms : out of question) to finish.

No, that’s the reason why it was cheap.:sunglasses:

oh wow

I have not tought to get such an amazing help :slight_smile:
Thanks a lot…

I have to check it out.
At the moment there is little time during daytime. I will check it out soon :slight_smile: probably in the night :expressionless:

Its intressting how hard it is to do a proper offset… I allready thougt about to build up the so called skeleton.
https://www.sthu.org/blog/14-skeleton-offset-topology/index.html

I wonder how to do so for variable offsets…

Further more I just think how this can be done with arcs within the polyline… which is what I’m looking for the last step…
Therefor, my first attempt was to do a physical intersection of extended curves, as the extend-method gives a native way to extend as an arc. But I guess it would not that hard to do it in a mathematical way too, as an Intersection of Line/Arc or Arc/Arc is not that special at all…

Please let me check ur attempts…
I feel kind of bad, for my inactivity :wink:

Again,
Thanks a lot

Greets
Mark

If you want something near skeleton look here

But I had the impression that you are a man devoted to find the Truth Out There, he he.

Anyway here’s a challenge with regard Laurent’s approach: Obvioulsy the only way to deal with self ccx curves is to split them (at the self ccx t values). But even so … there’s several situations where it’s hard (or impossible) to pick the right loop (it’s a bit kinda reverse engineering where the train is departed and you are waiting for some other [he’ll never come]). There’s also several cases where all-well + no self ccx means 100% bananas. Here’s one:

Tip: Locate a mess offset (not that difficult with the settings as in V2), place a point inside the donor poly , get the index and the offset thingy … and try to find the truth out there (but there’s none). DO NOT sort the loops with regard the distance between their CoG and the donor poly CoG (on first sight appears to be the solution - but life sucks).

PS: Recursion is required here in order to test properly ccx events (on the moved inwards/outwards segments) between a current, a next and a nextnext segment. If the dot between the next.Direction and the ccx current-next and next-nextnext is < 1 (inversed result: no-no) it means that it’s time to date another girl (set next == nextnext and keep trying) . I’ll post a derestricted abstract demo on that matter later. Kinda stuff the likes:

PS: Use the same R file posted above for that V2.

variableOffset_LaurentD_and_TheLord_V2.gh (140.2 KB)