为了账号安全,请及时绑定邮箱和手机立即绑定

仅在使用 fill() 时处理草图抛出 java.lang.AssertionError

仅在使用 fill() 时处理草图抛出 java.lang.AssertionError

慕娘9325324 2023-03-09 17:09:58
该研究项目是关于使用几何库从 .ttf 类型的字体文件中获取形状时沿贝塞尔曲线(递归多项式形式)处理文本。(它需要数据目录中的 ttf 文件才能运行。)目前,草图填充时似乎会抛出错误(任何颜色);用于代码绘制字符形状且贝塞尔曲线长度小于一定长度的部分。如果填充(); 未使用,草图似乎功能正常,没有任何错误。目标是使用 fill(); 函数来无误地填充字符。我试过了; 1) 去掉 beginContour();和结束轮廓();因为我认为它写得不正确。(我认为这是错误的,因为只有当形状是字母的内侧时才应该绘制轮廓,但目前,它不是第一个或最后一个形状时绘制轮廓)但是即使未使用轮廓函数(使用了填充();),草图也会抛出错误。2)认为与曲线的长度有关,所以尝试在绘制字母的部分添加if语句。到目前为止,我已经尝试使用从 void setup(){} 中的初始字体大小和字符串生成的 RGroup 的宽度,以及贝塞尔曲线的长度。if 语句中的条件示例如下;-RGroup形状时绘制字母' s width is smaller than the length of the curve - 当“缩进”(计算曲线上位置的变量)值小于曲线长度时绘制字母。(本例使草图仅在字母位于曲线内时才绘制字母,但仍然出现错误) - 当“缩进”(计算曲线位置的变量)值小于宽度时绘制字母的RGroup。我看不出问题到底出在哪里,所以我在草图中分享了整个代码,但我用“//*******”标记了我认为错误发生的地方。本研究基于以下链接。可以从以下链接查看几何库文档。有时在加载草图时会发生错误。大多数情况下,它加载正常,但当您稍微拖动该点时会抛出错误。错误代码有时是指曲线的控制点通过鼠标位置更新的点,但由于有时在加载草图时也会发生错误,所以我认为这不是与更新位置有关的问题。
查看完整描述

1 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

我不认为这会直接回答我的问题,但它确实阻止了在同时使用 fill() 和 P2D 渲染器时发生的错误。正如上面 laancelot 所指出的,主要问题确实似乎与堆栈溢出有关。所以我用下面两种方式解决了这个问题;结论:直接原因是数学公式表达不佳。


1) 在一个类中切换 RPoints。-我不认为这是错误发生的直接原因,因为在只重写代码的这一部分完成的阶段,错误仍然存在。但也许这是问题的一部分。我不知道。


2)重写代码表达公式的部分,以评估特定点的贝塞尔曲线。- 以前,该公式是通过使用阶数为 n 的贝塞尔曲线的显式定义得出的。因此,必须为 RPoint 点中的每个点计算(更像是制作)公式。正如关于贝塞尔曲线的维基百科页面上提到的,不推荐这种计算方式。-在修改后的代码中,用于扭曲文本的公式以多项式形式表示。因此,它能够在迭代 RPoint 点之前预先计算多项式的系数。这似乎已经解决了问题。


我仍然不确定到底是什么导致了这个问题,为什么它已经解决了,我应该展示代码的哪一部分来向其他人解释这个问题,所以我将分享已经重写的整个代码。您需要处理、几何库和数据文件夹中的 ttf 类型字体文件来测试代码。牵扯到修改版公式的地方我都标出来了。(还是真的很乱。。。)


//n number of points

int num = 4;

//arraylist to store the picked values

ArrayList<cntrlPoint> pt;


//import the geomerative library

import geomerative.*;




//string

String str = "(O_o)/ Oooh";


FloatList X;

FloatList Y;

FloatList SUM;


RClass rc;


void setup() {

  size(1000, 1000, P2D);

  pt = new ArrayList<cntrlPoint>();

  //pick a number of points with random positions

  for (int i=0; i<=num; i++) {

    float x = random(0, width);

    float y = random(0, height);

    pt.add(new cntrlPoint(x, y));

  }


  RG.init(this);

  rc = new RClass();   


  X = new FloatList();

  Y = new FloatList();  

  SUM = new FloatList();

}


void draw() {

  background(255);

  noFill();

  strokeWeight(2);

  drwCntrlPoints();

  drwCurve();

  gtArcLength();

  fill(0,255,0);

  rc.crtPoly(pt);

  rc.drwText();

}


void drwCntrlPoints() {

  //draw points

  beginShape();

  for (int i=0; i<=num; i++) {

    vertex(pt.get(i).x, pt.get(i).y);

  }

  endShape();


  for (int i=0; i<=num; i++) {

    ellipse(pt.get(i).x, pt.get(i).y, 10, 10);

  }

}


void drwCurve() {

  //draw curve

  float curveDetail = 0.01;

  float nfac = 1;

  for (int i=0; i<num; i++) {

    nfac *= (i+1);

  }

  int arcIndex = 0;

  strokeWeight(2);

  beginShape();

  for (float t=0; t<=1; t+=curveDetail) {

    float x = 0;

    float y = 0;

    arcIndex++;

    for (int i=0; i<=num; i++) {


      float coef = 1;

      float kfac = 1;

      float k_nfac = 1;

      for (int k=i; k>0; k--) {

        kfac *= k;

      }

      for (int k=(num-i); k>0; k--) {

        k_nfac *= k;

      }


      coef = nfac/(kfac*k_nfac);


      x += coef*(pow((1-t), num-i)*pow(t, i)*pt.get(i).x);

      y += coef*(pow((1-t), num-i)*pow(t, i)*pt.get(i).y);

    }

    vertex(x, y);

    X.set(arcIndex, x);

    Y.set(arcIndex, y);

  }

  endShape();

}


void gtArcLength() {

  //get arclength by pulling points from a floatlist

  int numberOfDivisions = X.size()-2;

  int maxPoint = numberOfDivisions+1;


  float sum = 0;


  float prevPointX = X.get(0);

  float prevPointY = Y.get(0);


  for (int i=1; i<=maxPoint; i++) {

    float pointX = X.get(i);

    float pointY = Y.get(i);

    sum += dist(pointX, pointY, prevPointX, prevPointY);

    SUM.set(i-1, sum);

    prevPointX = pointX;

    prevPointY = pointY;

  }

}


//*******factorial

int fact(int fa){

  if(fa==1){

    return 1;

  }

  if(fa==0){

    return 1;

  }

  else{

    return fa*fact(fa-1);

  }

}

//********************


int IndexOfLargestValueSmallerThan(float _targetArcLength) {

  int index = 0;

  for (int i=0; i<SUM.size()-1; i++) {

    if (SUM.get(i)<=_targetArcLength) {

      index = i;

    }

  }

  return index;

}


void mouseDragged() {

  int which = -1;

  if ((mouseX<width)&&(mouseX>0)&&(mouseY<height)&&(mouseY>0)) {

    for (int i=0; i<=num; i++) {

      if (dist(mouseX, mouseY, pt.get(i).x, pt.get(i).y)<80) {

        which = i;

      }

    }

    if (which>-1) {

      pt.get(which).update(mouseX, mouseY);

    }

  }

}


class RClass {

  //get ttf file

  //create rfont

  RFont fnt;

  //turn rfont to rgroup to get points

  RGroup rg;

  //going to get point in path, so that the characters in the string can be seperated

  RPoint [][]rp;


  //floatlist to store coefficients

  FloatList Cx;

  FloatList Cy;


  RClass() {

    fnt = new RFont("Zapfino.ttf", 100);

    rg = fnt.toGroup(str);

    rp = rg.getPointsInPaths();


    //RCommand.setSegmentAngle(random(0,HALF_PI)); 

    //RCommand.setSegmentator(RCommand.ADAPTATIVE);

    RCommand.setSegmentLength(3); 

    RCommand.setSegmentator(RCommand.UNIFORMLENGTH);


    Cx = new FloatList();

    Cy = new FloatList();

  }


  //**********************************here

  void crtPoly(ArrayList<cntrlPoint> _pt){

    float ptsize = _pt.size();

    for(int j=0; j<ptsize; j++){

      float coefx = 0;

      float coefy = 0;

      float pi = 1;

      float sigx = 0;

      float sigy = 0;

      for(int m=0; m<=j-1; m++){

        pi *= (ptsize-1-m);

      }

      for(int i=0; i<=j; i++){

        sigx += (pow(-1,i+j)*pt.get(i).x)/(fact(i)*fact(j-i));

        sigy += (pow(-1,i+j)*pt.get(i).y)/(fact(i)*fact(j-i));

      }

      coefx = pi*sigx;

      coefy = pi*sigy;

      Cx.set(j,coefx);

      Cy.set(j,coefy);

    }

  }

  //**************************************


  void drwText() {

    float indent = SUM.get(0);  


    beginShape();       

    for (int i=0; i<rp.length; i++) {

      if(i>0){

        beginContour();

      }

      for (int j=0; j<rp[i].length; j++) {


        float t = 0;


        indent = rp[i][j].x+SUM.get(0);


        float targetArcLength = indent;


        int index = IndexOfLargestValueSmallerThan(targetArcLength);


        if (SUM.get(index)==targetArcLength) {

          t = index/(SUM.size()-1);

        } else {

          float lengthBefore = SUM.get(index);

          float lengthAfter = SUM.get(index+1);

          float segmentLength = lengthAfter - lengthBefore;

          float segmentFraction = (targetArcLength - lengthBefore)/segmentLength;

          t = (index+segmentFraction)/(SUM.size()-1);

        }


        //***************************here

        float x = 0;

        float y = 0;

        float vx = 0;

        float vy = 0;


        for(int l=0; l<=num; l++){

          x += Cx.get(l)*pow(t,l);

          y += Cy.get(l)*pow(t,l);

        }


        for(int l=1; l<=num; l++){

          vx += l*Cx.get(l)*pow(t,l-1);

          vy += l*Cy.get(l)*pow(t,l-1);

        }

        //**************************************


        PVector P = new PVector(x, rp[i][j].y+y);


        PVector ldir = new PVector(P.x-x, P.y-y);



        PVector dir = new PVector(vy, -vx); 

        //

        ldir.rotate(dir.heading()+PI/2);


        vertex(x+ldir.x, y+ldir.y);

      }

      if(i>0&&i<rp.length){

        endContour();

      }

    }

    endShape();

  }

}


class cntrlPoint{

  float x,y;


  cntrlPoint(float _x, float _y){

    x = _x;

    y = _y;

  }


  void update(float _newx, float _newy){    

    x = _newx;

    y = _newy;   

  }


}



查看完整回答
反对 回复 2023-03-09
  • 1 回答
  • 0 关注
  • 109 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号