如何使用Conrec为轮廓线组装连续点的数组

时间:2011-03-31 08:41:55

标签: actionscript drawing concatenation series contour

我有一个Conrec的噩梦。我正在尝试使用Conrec在ActionScript中实现轮廓线。我已经看了java和javascript实现,但仍然卡住了。这些可以在这里找到:http://paulbourke.net/papers/conrec/

Conrec将获取网格数据并组合连续的轮廓线。问题是它不一定以连续的方式绘制这些线。例如,它将绘制A-> B,然后绘制C-> B,然后绘制C-> D而不是A,B,C,D等。

javascript实现似乎是在考虑这一点,并将指令序列化为一个绘制点数组。这也是我最终想要完成的事情。也就是说它采用来自核心Conrec逻辑的指令(例如:A-> B,C-> B,C-> D等)并将其组织成A,B,C,D系列。我认为它也会将系列作为多维数组返回以容纳虚线(例如:[[A,B,C,D],[E,F,G]])。最后一个功能是我在Actionscript中需要做的。

这最后一部分是我被困住的地方。暂时忽略Conrec(我已经放弃了查找Actionscript实现),如何将这些指令组织成一系列串行点?当Conrec给我“从X-> Y的绘制点”时,我怎么能首先检查X或Y是否已经在一个系列中并将X或Y(系列中没有哪个)附加到系列中?如果系列中既没有,则以X,Y作为起始集开始一个新系列。然后检查所有现有系列和连接系列的后续指令,如果它们现在在同一点开始和停止?此外,我需要能够允许一系列自我关闭(例如:A,B,C,A) - 一个循环(甚至可能吗?!)。

我希望这是有道理的。我不确定除了“连接”之外我是否还有一个技术术语。我也希望有人在那里与Conrec做过这件事,可以给我一些指示。

与此同时,我将继续关注此事,看看我是否可以拿出一些东西,但我对自己的能力没有信心。我真的很感谢一些退伍军人或专业人士的建议。

PS: 如果你知道从网格数据中绘制轮廓线的另一种方法,我愿意接受替代方案。但我必须能够在Actionscript中实现它。

3 个答案:

答案 0 :(得分:0)

好的,这是我第一次尝试获得我需要做的事情。我对结果并不十分满意,但似乎可以工作。

package {
  import flash.display.Sprite;

  public class lineSeriesPointConcat extends Sprite {
    public function lineSeriesPointConcat() {
      init();
    }
    //directions [X -> Y]
    //case 1: both counterclockwise, result is counterclockwise
    private var case1:Array = [
      ["G1", "F1"], 
      ["F1", "E1"], 

      ["D1", "C1"],
      ["C1", "B1"],
      ["B1", "A1"], 

      ["E1", "D1"], //link
      ["G1", "A1"] //loop
    ];

    //case 2: clockwise, counterclockwise, result is clockwise
    private var case2:Array = [
      ["E2", "F2"], 
      ["F2", "G2"], 

      ["D2", "C2"], 
      ["C2", "B2"], 
      ["B2", "A2"], 

      ["E2", "D2"], //link
      ["G2", "A2"] //loop
    ];

    //case 3: both clockwise, result is clockwise
    private var case3:Array = [
      ["E3", "F3"], 
      ["F3", "G3"], 

      ["A3", "B3"], 
      ["B3", "C3"], 
      ["C3", "D3"], 

      ["E3", "D3"], //link
      ["G3", "A3"] //loop
    ];

    //case 4: counterclockwise, clockwise, result is clockwise
    private var case4:Array = [
      ["G4", "F4"], 
      ["F4", "E4"], 

      ["A4", "B4"], 
      ["B4", "C4"], 
      ["C4", "D4"], 

      ["E4", "D4"], //link
      ["G4", "A4"] //loop
    ];


    private var collectedSeries:Array = [];

    private function init():void {
      var directions:Array = case1.concat(case2.concat(case3.concat(case4)));
      for each (var direction:Array in directions) {
        connect(direction[0], direction[1]);
      }
      trace ("final series:\n\t" + collectedSeries.join("\n\t"));
    }

    private function connect(from:String, to:String):void {
      var series:Array;
      var seriesStart:String;
      var seriesEnd:String;
      var seriesIndex:int;
      var n:int = collectedSeries.length;
      var i:int;
      for (i = 0; i < n; i++) {
        series = collectedSeries[i];
        seriesStart = series[0];
        seriesEnd = series[series.length - 1];

        if (seriesStart == to) {
          seriesStart = from;
          series.unshift(from);
          break;
        } else if (seriesStart == from) {
          seriesStart = to;
          series.unshift(to);
          break;
        } else if (seriesEnd == to) {
          seriesEnd = from;
          series.push(from);
          break;
        } else if (seriesEnd == from) {
          seriesEnd = to;
          series.push(to);
          break;
        }
      }

      if (i == n) {
        //this is a new series segment
        series = [from, to];
        seriesStart = from;
        seriesEnd = to;
        collectedSeries.push(series);
      }

      for (var j:int = 0; j < n; j++) {
        var compareSeries:Array = collectedSeries[j];
        if (compareSeries == series) {
          //don't compare the series to itself.
          continue;
        }
        var compSeriesStart:String = compareSeries[0];
        var compSeriesEnd:String = compareSeries[compareSeries.length - 1];
        if (compSeriesStart == compSeriesEnd) { 
          //this series loops on itself, it will not concatenate further
          continue;
        }
        if (compSeriesStart == seriesEnd) {
          trace ("case 1");
          series = series.concat(compareSeries.slice(1));
        } else if (compSeriesStart == seriesStart) {
          trace ("case 2");
          series = compareSeries.reverse().concat(series.slice(1));
        } else if (compSeriesEnd == seriesStart) {
          trace ("case 3");
          series = compareSeries.concat(series.slice(1));
        } else if (compSeriesEnd == seriesEnd) {
          trace ("case 4");
          series = compareSeries.concat(series.reverse().slice(1));
        } else {
          //no linkage between these two series
          continue;
        }
        collectedSeries[i] = series; //replace one of the two segements
        collectedSeries.splice(j, 1); //splice out the other
        break;
      }
      trace ("series: " + series + (i == n ? " new" : ""));
    }
  }
}

这将得到以下结果:

A1,G1,F1,E1,D1,C1,B1,A1

G2,A2,B2,C2,D2,E2,F2,G2

G3,A3,B3,C3,D3,E3,F3,G3

G4,A4,B4,C4,D4,E4,F4,G4

我仍然非常感谢我能得到的任何建议/反馈。 没有人使用Conrec吗?!

编辑:woops!我原来的splice()有一个bug!抱歉!现在修复

答案 1 :(得分:0)

我刚将ConRec移植到Actionscript3并且似乎工作正常,我没有彻底测试过, 但它按照我的预期绘制了我的轮廓。如果你愿意,试试看,我很好奇它是不是一个正确的端口。就在这里:

http://www.jvanderspek.com/DEV/ConRec/ConRec.as

答案 2 :(得分:-1)

好的,因此Flash可能有更好的选择。我刚发现这个链接,看起来令人印象深刻。如果这样可行,它可以避免原来的问题......

isolining package for ActionScript 3