質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

738閲覧

表示に穴を開けるには。

P5_USER

総合スコア73

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

0クリップ

投稿2018/03/06 08:37

前提・実現したいこと

以下の図の赤丸のようにスケールバーの指定の場所をくり抜いて奥の表示を出現させるテクニック、あるいは目的の描写を周囲に被らせないように行うトリミングのテクニックを知りたい。
イメージ説明
出典はこちら

発生している問題・エラーメッセージ

beginContour()とendContour()内に図に表示された赤丸内の白線をvertexで作成すると、リファレンス通り、指定した個所をくり抜いてくれるのですが、beginShape()とbeginContour()のコード内に座標変換や他の図形(例:rect、ellipse)を使うことが出来ないので、どうしたものかと行き詰っています。
###取り得る手法
1)一番奥のレイヤ(エディタ内では上の行)に赤丸内のラベルを潜ませて、何かしらの方法でくりぬく
→そのくり抜く方法とは?

2)一番手前のレイヤ(エディタ内では下の行)に枠からはみ出した部分をトリミングして指定した位置に貼り付ける。
→後ろを透かせつつトリムする方法がわからない。

該当のソースコード

一応ソースを載せます。
大雑把の説明ですが、1つ目のソースコードはsetup()とdraw()しか記述していません。2つ目にはdraw()の中にあるspeed_region()の中身を書いており、
一番下の15行がbeginContour()を使ってくり抜いている部分になっています。
それ以外のところはラベルを表示しているコードになっています。

processing

1import hypermedia.net.*; 2UDP udp; 3 4PFont Font;//HUDフォント 5float newX = 0, newY = 0; 6float bank; 7float font_size_small; 8float font_size_large; 9 10float theta = 0;//ピッチ各 11float phi = 0;//バンク角 12float psi = 0;//方位角 13float kvc = 0;//CAS 14float kph = 0;//気圧高度 15 16void setup() 17{ 18 size(displayWidth, displayHeight); 19 Font = loadFont("Verdana-48.vlw"); 20 strokeWeight(displayHeight/350); 21 22 //udp = new UDP (this, 60000); 23 //udp.listen(true); 24} 25 26void draw() 27{ 28 font_size_small = displayHeight/40; 29 font_size_large = displayHeight/30; 30 textFont(Font, font_size_small); 31 32 kvc = 50; 33 34 bank = radians(-phi); 35 36 background(255); 37 fill(0, 255, 0); 38 smooth(); 39 speed_region(); 40}
void speed_region() { float mask_width = displayWidth / 8.0; float mask_height = displayHeight / 7.5; int spd_label_max = 1000; //速度の最大表示はMAX1000 [kt] int spd_delta = 20;//速度の表示間隔は20 [kt] int spd_num = spd_label_max / spd_delta; float spd_scale_length = displayHeight * 0.35; float spd_num_distance = spd_scale_length / spd_num; float spd_num_reach = mask_width * 0.35; float spd_scale_main_reach = mask_width * 0.20; float spd_scale_sub_reach = mask_width * 0.10; float spd_num_exist; float spd_scale_sub_exist; float R = displayHeight / 50; textFont(Font, font_size_large); rectMode(CORNER); noStroke(); fill(0); rect(0, 0, mask_width, displayHeight);//速度計の背景をセット stroke(0, 255, 0); line(mask_width, mask_height, mask_width, displayHeight - mask_height); fill(0); translate(mask_width, displayHeight / 2); textAlign(RIGHT); //速度計表示 for (int i = 0; i <= spd_label_max; i += spd_delta) { float y = map(kvc, 0, 1000, 0, spd_scale_length * ((spd_label_max / spd_delta) - 30)); spd_num_exist = -(i * spd_num_distance) + y; spd_scale_sub_exist = spd_num_exist - spd_num_distance * (spd_label_max/100); fill(0, 255, 0); text(i, -spd_num_reach, spd_num_exist + font_size_large * 0.3); line(0, spd_num_exist, -spd_scale_main_reach, spd_num_exist); line(0, spd_scale_sub_exist, -spd_scale_sub_reach, spd_scale_sub_exist); } beginShape(); fill(0, 255, 0); scale(-1, 1); for (int i = 0; i < 3; i++) { vertex(R*cos(radians(360*i/3)), R*sin(radians(360*i/3))); } endShape(CLOSE); fill(0); scale(-1, 1); translate(-mask_width, -displayHeight / 2); noStroke(); rect(0, 0, displayWidth, mask_height);//速度計の上端の見切れをセット stroke(0, 255, 0); line(0, mask_height, mask_width, mask_height); translate(0, displayHeight); scale(1, -1); noStroke(); rect(0, 0, displayWidth, mask_height);//速度計の下端の見切れをセット stroke(0, 255, 0); line(0, mask_height, mask_width, mask_height); scale(1, -1); translate(0, -displayHeight); //noFill(); beginShape(); vertex(0, 0); vertex(mask_width, 0); vertex(mask_width, displayHeight); vertex(0, displayHeight); beginContour(); vertex(0, displayHeight / 15 + displayHeight / 2); vertex(mask_width / 1.25, displayHeight / 15 + displayHeight / 2); vertex(mask_width / 1.25, displayHeight / 45 + displayHeight / 2); vertex(mask_width / 1.10, displayHeight / 2); vertex(mask_width / 1.25, -displayHeight / 45 + displayHeight / 2); vertex(mask_width / 1.25, -displayHeight / 15 + displayHeight / 2); vertex(0, -displayHeight / 15 + displayHeight / 2); endContour(); endShape(CLOSE); }

補足情報(FW/ツールのバージョンなど)

processing 3.3.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

おっしゃっていることをちゃんと理解しているか自信がありませんが、2)の方法というのはこういうことでしょうか。
PGraphicsプレーンを作成して、画に載せて「吹き出し」を作って、外側部分をマーカー色で塗りつぶした上で最後にマーカー色をピクセル単位で透明にし(この辺がイケてない気がするけど)、メイン画面に貼り付けています。

Processing

1PFont Font; 2PGraphics pg; 3 4void setup() { 5 size(300, 300); 6 Font = createFont("メイリオ", 48); 7 pg=createGraphics(100, 100); 8} 9 10void draw() { 11 pg.beginDraw(); 12 pg.background(0); 13 pg.fill(255); 14 pg.textFont(Font, 48); 15 pg.text("0123", -10, 30); 16 pg.text("1234", -10, 70); 17 pg.text("2345", -10, 110); 18 pg.fill(128, 0, 0);//後で透明にするマーカー色 19 pg.stroke(255, 255, 0); 20 pg.strokeWeight(5); 21 pg.beginShape();//吹き出しの外側を塗りつぶす 22 pg.vertex(-10, -10);//枠線を表示させないために画面外に 23 pg.vertex(pg.width+10, -10); 24 pg.vertex(pg.width+10, pg.height+10); 25 pg.vertex(-10, pg.height+10); 26 pg.beginContour();//吹き出しのくり抜き描画 27 pg.vertex(10, 90); 28 pg.vertex(70, 90); 29 pg.vertex(70, 60); 30 pg.vertex(95, 50); 31 pg.vertex(70, 40); 32 pg.vertex(70, 10); 33 pg.vertex(10, 10); 34 pg.endContour(); 35 pg.endShape(CLOSE); 36 pg.loadPixels(); 37 for (int i=0; i<pg.pixels.length; i++) { 38 if (red(pg.pixels[i])==128) {//マーカー色を 39 pg.pixels[i]=color(0, 0, 0, 0);//透明に置き換える 40 } 41 } 42 pg.updatePixels(); 43 pg.endDraw(); 44 background(0, 128, 0); 45 image(pg, 100, 100);//透明色付きのPGraphicsを貼り付け 46} 47

追記:
1)の方も、こんなでいいのかなぁ。

Processing

1void setup() { 2 size(800, 600); 3 Font=createFont("メイリオ", 48); 4 font_size_large = height/30; 5} 6 7PFont Font; 8float font_size_large; 9float kvc = 0; 10 11void draw() { 12 speed_region(); 13} 14 15void speed_region() 16{ 17 float mask_width = width / 8.0; 18 float mask_height = height / 7.5; 19 int spd_label_max = 1000; //速度の最大表示はMAX1000 [kt] 20 int spd_delta = 20;//速度の表示間隔は20 [kt] 21 int spd_num = spd_label_max / spd_delta; 22 float spd_scale_length = height * 0.35; 23 float spd_num_distance = spd_scale_length / spd_num; 24 float spd_num_reach = mask_width * 0.35; 25 float spd_scale_main_reach = mask_width * 0.20; 26 float spd_scale_sub_reach = mask_width * 0.10; 27 float spd_num_exist; 28 float spd_scale_sub_exist; 29 float R = height / 50; 30 31 PGraphics pg=createGraphics((int)(mask_width+R/2), height); 32 33 pg.beginDraw(); 34 pg.background(255, 0, 0); 35 pg.textFont(Font, font_size_large); 36 pg.rectMode(CORNER); 37 pg.noStroke(); 38 pg.fill(200); 39 pg.stroke(0, 255, 0); 40 pg.rect(0,0,mask_width, height); 41 pg.translate(mask_width, height/2); 42 pg.fill(0); 43 pg.textAlign(RIGHT); 44 //速度計表示 45 for (int i = 0; i <= spd_label_max; i += spd_delta) 46 { 47 float y = map(kvc, 0, 1000, 0, spd_scale_length * ((spd_label_max / spd_delta) - 30)); 48 49 spd_num_exist = -(i * spd_num_distance) + y; 50 spd_scale_sub_exist = spd_num_exist - spd_num_distance * (spd_label_max/100); 51 pg.fill(0, 255, 0); 52 pg.text(i, -spd_num_reach, spd_num_exist + font_size_large * 0.3); 53 pg.line(0, spd_num_exist, -spd_scale_main_reach, spd_num_exist); 54 pg.line(0, spd_scale_sub_exist, -spd_scale_sub_reach, spd_scale_sub_exist); 55 } 56 pg.fill(0, 255, 0); 57 pg.beginShape(); 58 pg.scale(-1, 1); 59 for (int i = 0; i < 3; i++) { 60 pg.vertex(R*cos(radians(360*i/3)), R*sin(radians(360*i/3))); 61 } 62 pg.endShape(CLOSE); 63 pg.fill(255,0,0); 64 pg.resetMatrix(); 65 pg.beginShape();//くり抜くところを描画 66 pg.vertex(0, -height / 15 + height / 2); 67 pg.vertex(mask_width / 1.25, -height / 15 + height / 2); 68 pg.vertex(mask_width / 1.25, -height / 45 + height / 2); 69 pg.vertex(mask_width / 1.10, height / 2); 70 pg.vertex(mask_width / 1.25, height / 45 + height / 2); 71 pg.vertex(mask_width / 1.25, height / 15 + height / 2); 72 pg.vertex(0, height / 15 + height / 2); 73 pg.endShape(CLOSE); 74 pg.loadPixels(); 75 for(int i=0;i<pg.pixels.length;i++){ 76 if(red(pg.pixels[i])==255){ 77 pg.pixels[i]=color(0,0,0,0); 78 } 79 } 80 pg.updatePixels(); 81 pg.endDraw(); 82 background(0, 200, 200); 83//マスクの下のラベルを描く 84 translate(0,height/2); 85 fill(0); 86 rect(0,-height/15,mask_width,height*2/15); 87 fill(255); 88 textAlign(RIGHT,BOTTOM); 89 textFont(Font, font_size_large*2); 90 text("123",mask_width/1.25,0); 91 text("456",mask_width/1.25,height/15); 92 text("456",mask_width/1.25,height*2/15); 93 94 95 resetMatrix(); 96 image(pg, 0, 0);//速度計マスク(?)を被せる 97}

普通の描画では透明度をつけても、何かを描いた上から描くと下に描いてあるものが透過して見えるだけなので、PGraphicsに描いて、結果の一部の色を透過色に置き換えてやる、なんていうことをやっているわけですが。

投稿2018/03/18 14:24

編集2018/03/20 12:47
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問