スキップしてメイン コンテンツに移動

POLYLINEで一点鎖線を生成する。

グラフィックスで一点鎖線を自力で表示させるのは結構大変ではないけど、めんどい。
まず、線を分解して、線分の集まりにする。
また曲線は直線置換することを前提としとく。
別に、1/10000ミリの精度を必要とする工作機械じゃないんだから^^;
ということで、こんなことをするわけです。



で、まず、一点鎖線の定義ですが、
ここはよくあるlineTYpeの設定のように、繰り返す単位で定義します。



そうですね。データとしては、
double D[] = { 3,1,1,1 };
みたいなことです。
一般的に定義は偶数個、即ち、
描画部分の長さで始まり、
ブランクの長さで終わります。
だから、破線とかであれば、、
double D[] = {1,1};
みたいな定義となりますね。

それを実際のPOLYLINEに当てはめていく作業となりますよ。



さて問題は、、プログラミング上で、
どんなLOOPにするかっていうことです。




そう、図形の頂点としてのArrayの繰り返しと、
LINETYPEのパターンの繰り返しとなります。
2重LOOPというわけでは無いとこが、めんどいとこです。
要するに、LOOPが入れ子じゃないので、
別々に進んでいく感じとなります。

一般的には、直線の長さのほうがパターンの長さより長いことが多く、
頂点のLOOPの方が良いようなきもしますが、
曲線を直線置換すると、ひとうひとつの直線が短くなるし、
長かろうが短かろうが、
LINETYPEのパターンの長さと直線の長さが必ず一致するわけではないので、
それを踏まえた上で、こうしてみました。

while(1){
  for(w=0;w<dashN;w++){

  }
  break条件でbreak
}
まぁ、よくわからないかもですが、、まず無限LOOPのwhileをまわし、
その中でLINETYPEのARRAYをまわします。
主体をLINETYPEの方にもってきます。
それで、そのなかで、頂点の生成をしたり削ったりという謎のことをやります。

while(1){
  for(w=0;w<dashN;w++){
    double d  = dashAR[w];
    loalDashL  += d;
    dashL    += d;
    if(dashL < lineL){
      double xx,yy;
      getLinePoint(sx,sy,ex,ey,loalDashL,&xx,&yy);
      if(w % 2 == 0){
        P.type    = 1;
      }else{
        P.type    = 0;
      }
      P.x      = xx;
      P.y      = yy;
      pCtenB->setdata(&P);
      pCurP = pCtenB->getdata(pCtenB->getCount()-1);
    }else{
      double delt = dashL - lineL;
      loalDashL  = delt;
      double xx,yy;
      if(w % 2 == 0){
        P.type    = 2;
      }else{
        P.type    = 0;
      }
      P.x      = ex;
      P.y      = ey;
      pCtenB->setdata(&P);
      pCurP = pCtenB->getdata(pCtenB->getCount()-1);
      p = q;
      q = pCtenC->getdata(z%n);      z++;
      if(z > nn){
        bBreak = true;
        break;
      }
      sx = ex;
      sy = ey;
      ex  = q->x;
      ey  = q->y;
      getLinePoint(sx,sy,ex,ey,delt,&xx,&yy);
      P.x      = xx;
      P.y      = yy;
      if(P.type == 0){
        pCurP->x = P.x;
        pCurP->y = P.y;
      }else{
        pCtenB->setdata(&P);
        pCurP = pCtenB->getdata(pCtenB->getCount()-1);
      }
      dx  = ex - sx;
      dy  = ey - sy;
      dd  = pow(dx * dx + dy * dy, 0.5);
      lineL    += dd;            //  実際の点のTOTAL
      if(z > nn){
        bBreak = true;
        break;
      }
    }
  }
  if(bBreak)  break;
}
int lastN = pCtenB->getCount()-1;
if(lastN > 0){
  if(pCurP->type == 0)  pCtenB->deleteData(lastN);
}
で、、できあがったサンプルが以下。


頂点を表示させるとこうなります。
 

めでたしめでたし。(o^^o)

コメント

このブログの人気の投稿

平面的な台形変形と奥行的な台形変形(2)

ということで前回のつづきですが、 3点の消点でやってみます。 ●元 ●平面的変形(もはや台形じゃないけど^^;) ●立体的変形の平面投影っぽく ●無理やり感満載の3消点 こんな感じとなりますね。 void getDaikeiPersPos(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4,double* pX,double* pY,double tx,double ty,double delt){ double xa,ya,xb,yb,xa2,ya2,xb2,yb2; xa = ya = xb = yb = xa2 = ya2 = xb2 = yb2 = 0; getDaikeiPersPosX(x1,y1,x2,y2,x3,y3,x4,y4 ,&xa,&ya,&xb,&yb ,tx,delt); getDaikeiPersPosY(x1,y1,x2,y2,x3,y3,x4,y4 ,&xa2,&ya2,&xb2,&yb2 ,ty,delt); bool b = vCrossPoint(xa,ya, xb,yb, xa2,ya2, xb2,yb2,pX,pY); } void getDaikeiPersPosX(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4 ,double* xa,double* ya,double* xb,double* yb,double t,double delt){ if(t<0) t = 0; if(t>1) t = 1; double xa1,ya1,xa2,ya2,xa3,ya3,xa4,ya4,xa5,ya5,xa6,ya6; double cx,cy,xx,yy; xa1 = ya1 = xa2 = ya2 = xa3 = ya3 = xa4 = ya4 = xa5 = ya5 = xa6 = ya6 = 0; cx = cy = xx = yy = 0; double tA = ...

Ratchet@PHPで自宅にhttpsでWebsocketするサンプルを動かす

今日のゴールは、外から自宅にhttpsでWebsocket@Rachet@PHP@WindowsServerするサンプルを動かすことです。 ※そのうち、Websocket@libwebsocket@Ubuntuをやりますね。 そもそもRatchetはポートを指定してws:// をうけつけてくれるものなので、 自宅サーバがそもそもNginxでリバースプロキシしてるので、 難しいことはせずに、それに則った形で設定を行います。 要するに、wss://をリバースプロキシで受けて、Ratchetが動作するサーバへ転送するだけです。 もちろん、プロキシにはUpgradeヘッダ(HTTP 1.1)への対応が必要となりますね。 絵にかくと、以下ですね。 自宅のhttpsはletsencryptというのを使用しています。 Windowsで使う場合には、以下が参考になりますね。 https://webbibouroku.com/Blog/Article/letsencrypt-setting ここではHTTPSそのものの設定に関しては記述しませんです。 リバースプロキシしてるNginxのconfの該当部分は以下としました。 ※abcd.comは実際のドメインに。 server { listen 443; include ssl-abcd.com.conf; server_name ws.abcd.com; proxy_set_header Host $http_host; access_log /log/ssl-ws-abcd.com.log main; location / { proxy_pass http://192.168.xxx.xxx:8080; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; } } これによって、javascriptから、 wss://ws.abcd.com が、 http:192.168.xxx.xxx:8080 に転送されることになるので、転送先にRatc...

意外とめんどいPHPからshellとかexecをWindowsでする場合の話。

いや、意外とめんどい話でした。 たとえば、CMD(BAT)ファイルで以下を実行させてみます。 ●TEST.cmd● REM ------------------- start a.exe start b.exe REM ------------------- pause そう、a.exeもb.exeも実行され、終了を待つことなくpause入ります。 そう、じゃぁ、phpで、以下をやってみます。 shell_exec('TEST.cmd' ); あれこれ とか exec('TEST.cmd' ); あれこれ すると、どうでしょう。 このa.exeとb.exeが両方終わるまで、待たされてしまい、 【あれこれ】のとこに来てくれません。 やりっぱなし! ができないのです。 うぅーん。LinuxでPHPならforkとかできる(ハズな)んだけど。 どうなってんだろ。これ(>_<) ここ、トリッキーないかがわしいことやればできるのかもしれないけど (できないかもですが^^;) つきつめるとこじゃないので、 どうせ最後はC++にするつもりなので、Jobコントローラーの部分なので、 素直にC++で描いてしまおうかとも思ったけど、 いろいろ調べた結果、psexecでできそうな感じもしたんだけど、 やってみるとできない。うぅーーん。 できるかぎりPHP という方針、若干、無理があったかな^^; じゃぁ、ってことで、プロセスを立ち上げっぱなしで戻ってくるEXEを作ってみた結果、 CreateProcessだと戻ってこない ShellExecuteなら戻ってくる ということがわかったので、そういうEXEを経由し、 exec("redshell -proc:php.exe z.php"); exec("redshell -proc:php.exe z2.php"); って感じで連続実行させるテストをしてみます。 ●a.php <?php exec("redshell -proc:php.exe z.php"); exec("redshell -proc:php.exe z2.php"); for($...