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

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

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

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

Q&A

解決済

1回答

3288閲覧

Processingでアナログ時計の針を画像(png)で作りたい

noutore

総合スコア7

Processing

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

0グッド

0クリップ

投稿2020/11/21 04:43

Processing初心者です。

Processingでアナログ時計の針を画像(png)で作りたいのですが、
参考になるコードを探しても見つかりません。

短針、長針、秒針をそれぞれ画像(png)で作り
秒針は連続秒針(スイープセコンド・スイープ)が理想です。

宜しくお願いいたします。

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

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

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

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

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

thkana

2020/11/21 04:46

> 参考になるコードを探しても見つかりません。 だから、作るんでしょ? 画像であることが問題なら、画像じゃなかったらできるんですね? では、まずそのプログラムを示して下さい。そこから改造しましょう。
noutore

2020/11/21 05:02

参考にしたコードに7行目と19行目を書き加えました。 int cx, cy; float secondsRadius; float minutesRadius; float hoursRadius; float clockDiameter; void setup() { img = loadImage(“sample.png"); size(640, 360); stroke(255); int radius = min(width, height) / 2; secondsRadius = radius * 0.72; minutesRadius = radius * 0.60; hoursRadius = radius * 0.50; clockDiameter = radius * 1.8; cx = width / 2; cy = height / 2; } void draw() { image(img, 0, 0); background(0); // Draw the clock background fill(80); noStroke(); ellipse(cx, cy, clockDiameter, clockDiameter); // Angles for sin() and cos() start at 3 o'clock; // subtract HALF_PI to make them start at the top float s = map(millis(), 0, 60000, 0, TWO_PI) - HALF_PI; float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI; // Draw the hands of the clock stroke(255); strokeWeight(1); line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius); strokeWeight(2); line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius); strokeWeight(4); line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius); // Draw the minute ticks strokeWeight(2); beginShape(POINTS); for (int a = 0; a < 360; a+=6) { float angle = radians(a); float x = cx + cos(angle) * secondsRadius; float y = cy + sin(angle) * secondsRadius; vertex(x, y); } endShape(); }
guest

回答1

0

ベストアンサー

針を画像から描画することと、
秒針をなめらかに(正しく)動かす操作を組み込んでみました。

Processing

1PImage img; 2int cx, cy; 3float secondsRadius; 4float clockDiameter; 5 6PImage hourHand, minuteHand, secondHand; 7int millisOffset; 8float multiplier=1; 9 10void setup() { 11 // img = loadImage("sample.png");//背景画像?はダミーで 12 size(640, 360); 13 img=get(0, 0, 640, 360); 14 stroke(255); 15 int radius = min(width, height)/2; 16 secondsRadius = radius * 0.72; 17 clockDiameter = radius * 1.8; 18 cx = width / 2; 19 cy = height / 2; 20 21 //針画像はイラスト素材のサイトからググったもの。実は時計じゃないみたいな? 22 PImage set=loadImage("https://bvews.jpn.org/images/gauge-needle-sample.png"); 23 //画像から針を切り出し。各画像の中心が回転原点になる(別途原点情報を持たなくてよい)ように、敢えて大きく切り抜いている 24 hourHand = set.get(22, 25, 30, 107*2); 25 minuteHand = set.get(85, 0, 30, 132*2); 26 secondHand = set.get(148, 0, 30, 131*2); 27 28 multiplier=secondsRadius/132; 29 //millis()はプログラム開始からの通算ミリ秒であって、時刻の秒の下位ではない 30 //ので、「秒の変わり目」に対応するミリ秒の下位を求める 31 int sec=second(); 32 do { 33 millisOffset=millis()%1000; 34 } while (sec==second()); 35} 36 37void drawHands() { 38 float s = map(second()+norm((millis()-millisOffset)%1000, 0, 1000), 0, 60, 0, TWO_PI); 39 float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI); 40 float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2); 41 translate(cx, cy); 42 rotate(s); 43 scale(multiplier, multiplier); 44 image(secondHand, -secondHand.width/2, -secondHand.height/2); 45 rotate(m-s);//既にs回っているのでこれでmだけ回ったことになる 46 image(minuteHand, -minuteHand.width/2, -minuteHand.height/2); 47 rotate(h-m);//hだけ回ったことに 48 image(hourHand, -hourHand.width/2, -hourHand.height/2); 49 resetMatrix();//一応元に戻しておく 50} 51 52void draw() { 53 background(0); 54 image(img, 0, 0); //この順序でないと背景が表示されないのでは? 55 56 // Draw the clock background 57 fill(80); 58 noStroke(); 59 ellipse(cx, cy, clockDiameter, clockDiameter); 60 61 // Draw the minute ticks 62 stroke(255); 63 strokeWeight(2); 64 beginShape(POINTS); 65 for (int a = 0; a < 360; a+=6) { 66 float angle = radians(a); 67 float x = cx + cos(angle) * secondsRadius; 68 float y = cy + sin(angle) * secondsRadius; 69 vertex(x, y); 70 } 71 endShape(); 72 73 drawHands();//針の描画 74}

追記 単独の針の画像で描く

なんだか難しいと言われてしまったのでソコだけのサンプル。

原理的には同じことで長針短針秒針3回描けばいいので針一本分だけ描いてみる。

Processing

1//本題とは関係ない参考:針の画像を描く 2//背景を透過にするためmaskを使ってpngでsaveする 3PImage img1,msk; 4size(100,200); 5noStroke(); 6fill(0); 7background(255); 8triangle(50,20,45,180,55,180); 9circle(50,180,20); 10img1=get(); 11msk=img1.get(); 12msk.filter(INVERT); 13img1.mask(msk); 14img1.save("hand1.png");

これで次の画像ファイルが生成される。
針の画像

このファイルを読み込んで、ぐるぐる回せばよい

Processing

1PImage hand1; 2final int refX=50; //針画像で回転の中心座標x 3final int refY=180; //針画像で回転の中心座標y 4final int centerX=400; //回転の中心x 5final int centerY=240; //回転の中心y 6float angle=0; 7 8void setup(){ 9 size(640,480); 10 hand1=loadImage("https://teratail-v2.storage.googleapis.com/"+ 11"uploads/contributed_images/fdf1674fe63b0bec82085f26b192c116.png"); 12//URL文字列が長くなって見にくいのが嫌で分割している。 13} 14 15void draw(){ 16 background(0xc0); 17 translate(centerX,centerY); //centerX,centerYを新たな0,0とする 18 rotate(angle); //0,0を中心に座標系を回す 19 image(hand1,-refX,-refY); //refX,refYが0,0に来るように描画 20 angle+=0.01; 21}

投稿2020/11/21 06:35

編集2020/11/21 14:23
thkana

総合スコア7659

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

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

noutore

2020/11/21 07:18

thkanaさま 回答いただき、有難うございます。 そして、丁寧な解説も付けていただき感動しております。 1枚の画像を読み込み、それぞれの針にされておりますが 申し訳ございませんが、この箇所がかなり難しいです。 そこで大変恐縮ですが、お願いがございます。 それぞれの針に、それぞれの画像を読み込んで設定した場合は どのようになるか、ご教授いただけないでしょうか? それぞれの針に、それぞれの画像を読み込みが もし可能であれば、宜しくお願い致します。
thkana

2020/11/21 07:48

何ら難しいことはしていません。 https://processing.org/reference/PImage_get_.html 画像の一部を切り出して、保存しただけです。 > それぞれの針に、それぞれの画像を読み込んで そうしたいならそうして下さい。画像も提示されていませんし、質問に書いていないことは私には知りようがないです。 画像をファイルから読み出す方法はあなたの提示したプログラムに書かれていますからご承知のものと思います。
noutore

2020/11/23 05:36

thkanaさま 回答いただき、有難うございます。 2020/11/21にいただいた参考URLと その後いただいた追記(単独の針の画像で描く)を頼りに Processingを動かせました。 本当に有難うございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問