minikoro

Yasuhide Yamashita mini webblog.

iBeaconを使用した目覚ましiOSアプリ製作のお話(後半)

2015.Dec.31 Thu

wub_title1

2015年の夏にiOSアプリをリリースしたお話前半です。前半はこちら

iBeaconも調達出来てじゃぁ申請だぜってApple様にアプリ申請をしたら「Yo!お前のアプリiBeacon使ってるみたいだけど俺らiBeacon持って無いんで送ってこいよ、カリフォルニアにな!」って言われて、いやいやいやいやiBeacon無いとか意味わかんないんですけど、おたくの場所に無かったらどこにあるの?って言ってもはじまらないので渋々郵送。その後晴れてリリース。

ちなみにアプリデザイン部分ですがビジュアル部分は鈴鹿芳康先生のピンホール作品。

wub_img3

サイトのイラストはイケメンデザイナーのENPIZ氏(ラインスタンプはこちら)にご協力頂きました。ありがとうございました(m_ _m)

wub_img4

そんなこんなで無事一式作成出来ましたWake Up BeaconですがDL数の伸びは芳しく無い感じで…(笑)。wub.lifeへのアクセス数も少なく作り始めの時点で危惧しておりました広告怪獣大決戦市場に見事に埋もれております。っていうかそもそも露出が少ないという問題もありますが(汗)。情報発信についてはもっと努力しないとなぁと改めて。

ともあれ色々と得るものが多かったので良かったです。まだまだ工夫の余地はあるので引き続き試行錯誤しつつ、次のアプリなりサービスなりにもチャレンジしていきたいと思います。

大石社長始め、鈴鹿先生、ENPIZ氏、ご協力頂きほんとうにありがとうございました(m_ _m)

Tags : Creative iOS

iBeaconを使用した目覚ましiOSアプリ製作のお話(前半)

2015.Dec.31 Thu

wub_title1

2015年の夏にiOSアプリをリリースしたお話前半です。

動機としては世の中はアプリなんでiOSアプリでブイブイ言わせてやるぜっ!て訳では無く、むしろモバイルアプリは作るよりも作った後の宣伝が大手様の怪獣大決戦市場とのお話をよく聞くので、個人で作ったものは情報の海に埋没するしかないよね、怖いよねって感じなのですが、Swiftもリリースされてちょっと落ち着いた頃合いということでチャレンジしてみようというふわっとした動機です。@fladdict氏のこの発言にぶっ刺されたというのもありますが^^;。

で、何作ろうかなということでセンサー系楽しそうという安直な発想からプログラム的にも比較的導入しやすいiBeaconをチョイス。ってもiBeaconは作る手段であって作る目的にはならないのでもうひとひねり。スマートフォンを自宅やPCの鍵にしたり的なお話も多々あるということでなんか日常のトリガーにならんもんかなと模索。照明やらテレビやらも考えたけど単体で完結したいのでもうちょい軽めな感じは無いもかしら、日常的なスイッチは…、目覚ましかねーということで目覚ましアプリに。アイディアとしてはiBeaconを目覚ましのスイッチにして、洗面台に置いておけば目覚まし止めてそのまま顔を洗えていい感じに起きれるのではという発想。

wub_img1

目覚ましアプリは大量にあるのでどんなものかちょっと調査。変わったもので言えば計算問題解かないと止まらないとか、全力でふりふりしないと止まらないとか多数。「起きて目覚ましを止める」という行為に制約を設けるってのは有りといえばアリだけど、そもそも起きるがつらいのに起きた直後に全力で頭使うとか、全力で体動かすとかドMプレイつらいし、起きてそんなこと出来る気力あればそもそも起きれそう。布団から這い出すことで精一杯なのでそこは変えないというか「目覚ましが鳴って、布団から出て、顔を洗う」というサイクル以外の要素はそもそも出来ないよねってことで目覚ましのスイッチを切り出すってのはアリだと自分で納得、製作開始。

学習期間も含めると2014年の夏あたりからボチボチ着手してたのですが、当初からあった最大の問題点は作ったあとiBeaconどうすんのという問題。しかしながらそこは半年もすればiBeacon個人で買えるようになってんじゃね?という根拠の無い予想で放置、とりあえずアプリ製作。で、2014年年末にはプログラム的な問題はほぼクリア出来てリリース準備、のタイミングでフィードテイラー様が「そら用心」なるアプリをリリース。こちらはiBeaconを玄関に置いておき外出のタイミングで傘を忘れないように通知してくれる素敵アプリで、iBeaconセンサーの「そらビーコン」もアプリとは別に販売されてます。

フィードテイラー様の大石社長とは何度かお会いさせて頂いたことがあるのでこれはダメ元で突撃質問しか無い「iBeaconどうやって調達しているのか教えて貰えませんか?」と。ビジネス的に「それは内緒です。」と言われても仕方ないと思っていたのですが「いいですよ:)」と一つ返事頂き、直接お会いさせて頂き色々と教えて頂きました。その節は神対応本当にありがとうございました。

wub_img1

そんな感じでiBeaconもなんとか調達出来そうになりリリースにむけてごりごり前進です。なんか長くなったのでリリースに関するお話は後半で。

Tags : Creative iOS

Processingでオプ・アートの模写

2015.Dec.17 Thu

Vonal_Stri

Processingの学習素材としてVictor Vasarely先生の作品を模写した時にやっぱ良く出来てるなーという発見のお話です。本記事にてProcessing Advent Calendar 2015にも参加させて頂きました。主催のp5infoさんありがとうございます(m_ _m)

というこで模写を行ったのはトップ画像となっている1975年作のVonal Stri。オプ・アートのwikiはこちら

まずはロジックに落とし込むべくルール探し。最初に着目したのは中心軸。中心軸を基準に長方形を何かいい感じに描画出来ないかと模索。

Vonal_Stri_idea1

が、イメージが湧きにくくそもそも「いい感じ」が何者かわからないので却下。続いて第2案。四隅の移動軌跡に着目。

Vonal_Stri_idea2

すっきまとまりそうな感じなのでこの軌跡をスケッチ。

Vonal_Stri_idea3

なんとなくそれっぽくなりそうな予感。

ただこのまま点をつなぐと左側の円弧と右側の円弧の高さが合わないので高さは左側の円弧を基準にしようと考案。

Vonal_Stri_idea4

合わせて色もランダムに割り当て段階的に近似色を入れ子で配色。すると以下の感じに。

Vonal_Stri_idea5

だいぶいい感じになったけどなんか右半分のが直線に。ここでかなり頭を悩ます、ひねる、苦しむ。で、何日か寝かして電車に乗ってる時に閃き車内で1人突然ニヤニヤする、という流れ。

要因は高さ部分を左の円弧のY座標を基準としてるところで、その左の円弧描画時の角度増加が単純にフレームの増加に合わせて行われていたところ。

Vonal_Stri_idea6

その修正をしてあげると晴れて良い感じに。

Vonal_Stri_idea7

ちなみにこいつ動きます。ちょっと重いですけど縮小版貼っときます。Processing.js版の動いてるものはポップアップでこちらをどうぞ。四角の数や色はランダム生成となっております。

Vonal_Stri_idea8

ということでやっぱりしっかり考えられてるなーと感心した模写でした。新しいものを生み出すものも大事ですが既存の良いものももっとしっかり学ばねば。京都でスケッチ勉強会やりたい。コードは本文読みにくくなるので別記事にて。

※冒頭の画像はwikiart.orgのサイトより引用させて頂きました(m_ _m)

Tags : Creative Javascript Processing

Processingでオプ・アートの模写:Source

2015.Dec.17 Thu

Processingでオプ・アートの模写記事でのソースです。なんか色々もうちょっと上手く書く方法がありそうな感じですが^^;(223行目はバグで表示されているので無視してくださいませ)(m_ _m)。
int squareSize;					// 初期正方形のサイズ
float addSquareVal;				// 追加タイミングの基準
float tempSquareVal;				// 追加タイミング比較用
ArrayList squareArrayList;		// 描画オブジェクトArrayList
float upVal;

int[] colorH;					// ベースカラー:0-360
int[] colorS;					// ベースカラー:30-100
int[] colorB;					// ベースカラー:30-100
int[] colorUpBaseH;				// 色増減値
int[] colorUpBaseS;
int[] colorUpBaseB;
int[] colorSwitchH;				// 増減スイッチ0/1:1がプラス
int[] colorSwitchS;
int[] colorSwitchB;
int colorType;					// 使用カラーパターン判別

void setup(){
	squareSize = int(random(5,8));
	addSquareVal = random(1,3);
	tempSquareVal = 0;
	upVal = 0.1;

	colorMode(HSB,360,100,100);
	size(500,500);
	rectMode(CORNER);
	background(0);
	noStroke();
	frameRate(400);

	// HSBカラー関連用の変数を初期化。
	colorH = new int[2];
	colorS = new int[2];
	colorB = new int[2];
	colorUpBaseH = new int[2];
	colorUpBaseS = new int[2];
	colorUpBaseB = new int[2];
	colorSwitchH = new int[2];
	colorSwitchS = new int[2];
	colorSwitchB = new int[2];

	for(int i = 0; i < 2; i++) {
		colorH[i] = round(random(0,360));
		colorS[i] = round(random(30,100));
		colorB[i] = round(random(30,100));
		colorUpBaseH[i] = round(random(1,15));
		colorUpBaseS[i] = round(random(1,5));
		colorUpBaseB[i] = round(random(1,5));
		colorSwitchH[i] = round(random(0,1));
		colorSwitchS[i] = round(random(0,1));
		colorSwitchB[i] = round(random(0,1));
	}

	colorType = 1;

	squareArrayList = new ArrayList();
	squareArrayList.add(new Square(width,height,squareSize,upVal, colorH[0], colorS[0], colorB[0]));
}

void draw() {
	for(int i = 0; i < squareArrayList.size(); i++) {
		// 枠外に出たオブジェクトは削除
		if(squareArrayList.get(i).delFlg) {
			squareArrayList.remove(i);
		} else {
			squareArrayList.get(i).makeSquare();
		}
	}

	tempSquareVal += upVal;
	if(tempSquareVal >= addSquareVal) {
		// カラーの書き換え
		if(colorSwitchH[colorType] == 0) {
			// 減算パターン
			colorH[colorType] -= colorUpBaseH[colorType];
			if(colorH[colorType] < 0) {
				colorH[colorType] = 0;
				colorSwitchH[colorType] = 1;
			}
		} else {
			// 加算パターン
			colorH[colorType] += colorUpBaseH[colorType];
			if(colorH[colorType] > 360) {
				colorH[colorType] = 360;
				colorSwitchH[colorType] = 0;
			}
		}

		if(colorSwitchS[colorType] == 0) {
			// 減算パターン
			colorS[colorType] -= colorUpBaseS[colorType];
			if(colorS[colorType] < 0) {
				colorS[colorType] = 0;
				colorSwitchS[colorType] = 1;
			}
		} else {
			// 加算パターン
			colorS[colorType] += colorUpBaseS[colorType];
			if(colorS[colorType] > 100) {
				colorS[colorType] = 100;
				colorSwitchS[colorType] = 0;
			}
		}

		if(colorSwitchB[colorType] == 0) {
			// 減算パターン
			colorB[colorType] -= colorUpBaseB[colorType];
			if(colorB[colorType] < 0) {
				colorB[colorType] = 0;
				colorSwitchB[colorType] = 1;
			}
		} else {
			// 加算パターン
			colorB[colorType] += colorUpBaseB[colorType];
			if(colorB[colorType] > 100) {
				colorB[colorType] = 100;
				colorSwitchB[colorType] = 0;
			}
		}

		squareArrayList.add(new Square(width,height,squareSize,upVal, colorH[colorType], colorS[colorType], colorB[colorType]));

		// カラーパターンを切り替え
		switch (colorType) {
			case 0:
				colorType = 1;
				break;
			case 1:
				colorType = 0;
				break;
		}

		// 追加サイズ比較用の値を初期化。
		tempSquareVal = 0;
	}
}


class Square {
	float w;
	float h;
	float halfCirclAngle;			// 縦円の角度
	float topQuarterAngleVal;		// 上1/4円の角度
	float bottomQuarterAngleVal;		// 下1/4円の角度
	int squareSize;				// 初期正方形のサイズ
	float cercleR;				// 円の半径
	float upVal;
	boolean delFlg;				// 削除フラグ
	int colorH;
	int colorS;
	int colorB;
	float afterVal;				// 90度分の描画の後の増減。

	/**
	 * コンストラクタ
	 */
	Square(int w_, int h_, int s_, float u_, int colorH_, int colorS_, int colorB_) {
		w = w_;
		h = h_;
		upVal = u_;
		halfCirclAngle = 0;
		topQuarterAngleVal = 270;
		bottomQuarterAngleVal = 90;
		squareSize = s_;
		cercleR = (w-squareSize)/2;
		delFlg = false;
		colorH = colorH_;
		colorS = colorS_;
		colorB = colorB_;
		afterVal = 0;
	}

	void makeSquare() {
		float halfCirclTopX;			// 左半円上座標軸
		float halfCirclTopY;
		float halfCirclBottomY;
		float topQuarterCirclX;			// 上1/4円下座標軸
		float objHeight;
		float objWidth;

		fill(colorH,colorS,colorB);

		if(topQuarterAngleVal <= 360) {
			// 1/4円を描くまでは通常の描画
			// 左1/4円の角度(上下共通)
			// 角度を加速度的に増加することでY座標の増加も加速度的になる
			halfCirclAngle = 90+90*sin(radians(topQuarterAngleVal));

			// 左縦円上座標軸
			halfCirclTopX = cercleR * cos(radians(halfCirclAngle));
			halfCirclTopY = -cercleR * sin(radians(halfCirclAngle)) + cercleR;

			// 左縦円下座標軸
			halfCirclBottomY = cercleR * sin(radians(halfCirclAngle)) + cercleR + squareSize;

			// 右1/4円上座標軸
			topQuarterCirclX = cercleR * cos(radians(bottomQuarterAngleVal)) + cercleR + squareSize;

			// オブジェクトの高さを算出
			objHeight = halfCirclBottomY - halfCirclTopY;
			objWidth = topQuarterCirclX - halfCirclTopX;
			rect(halfCirclTopX,halfCirclTopY,objWidth,objHeight);

			// 角度調整
			topQuarterAngleVal += upVal;
			bottomQuarterAngleVal -= upVal;
		} else {
			// 1/4円を描いた場合は正方形での増加となる
			afterVal += 1;
			halfCirclTopX = 0 - afterVal;
			halfCirclTopY = 0 - afterVal;
			objWidth = w + (afterVal * 2);
			objHeight = h+ (afterVal * 2);
			rect(halfCirclTopX,halfCirclTopY,objWidth,objHeight);
		}

		// 枠外エリア描画判別
		if(objWidth >= (w + 50) && objHeight >= (h + 50)) {
			delFlg = true;
		}
	}
}
Tags : Creative Javascript Processing

Processingで諸々学習 その11

2015.Dec.02 Wed

acceleration

ということでフォース(力)の学習。
これで今日から僕もジェダイマスター。この知識をつかえば手をかざして人や物を浮かしたりふっとばしたり出来ます。

というジェダイのフォースじゃ無くて重力とか摩擦(散逸力)とか万有引力の法則とかです。今回のスケッチでガリレオ・ガリレイの「ピサの斜塔から大小二つの金属の玉を落とす」を理屈で理解出来たのはうれすぃ。

例により別窓で。草間彌生チックな感じでオサレ。

と、色々素敵な感じになってるのですが何が一番ステキかって言うと、散逸力とか万有引力って単語並べたら無条件で偏差値上がった気分になれるのが一番ステキ。

Tags : Creative Javascript Processing