ユニファ開発者ブログ

ユニファ株式会社プロダクトデベロップメント本部メンバーによるブログです。

時間帯被るかどうかから長方形の衝突検知

こんにちは、午睡チェックサーバーエンドエンジニアのちょうです。最近開発で見つかったちょっと難しい問題について話したいです。それは時間帯が被ってるかどうかのチェックです。

時間帯

例えば

  • 午後3時から午後4時
  • 午後5時から午後6時

という2つの時間帯は被らないとし、

  • 午前10時から午後4時
  • 午後3時から午後5時

が被るとしたら、どうやって時間帯が被るかをチェックしますか。

時間帯を表記しやすいために、[15:00, 16:00] は午後3時から午後4時の意味をします。なお、[15:00, 16:00][16:00, 17:00] は被らないとします。

個別のケースを考えるより、すべて可能なケースをここにリストアップしました。

f:id:unifa_tech:20190603190445p:plain

2つの時間帯の関係は全部6ケースあります。以下金色の時間帯1は[S1, E1]、水色の時間帯2は[S2, E2]とします。

  1. 被らない、E1 <= S2
  2. 被る、S1 < S2 < E1
  3. 被る、S2 <= S1 < E1 <= E2
  4. 被る、S1 <= S2 < E2 <= E1
  5. 被る、S1 < E2 < E1
  6. 被らない、E2 <= S1

被るケースが4個あるので、4ケースの一つに当てはまれば被ります。とはいえ、4つのケースに共通点あまりないし、そのままコードにするのは分かりにくいです。

ここで一つのテクニックは被るケース以外のケース、つまり被らないケース、の逆にすれば簡単にできます。

  ALL CASES - <CASE 1> - <CASE 6>
=!<CASE 1>   && !<CASE 6>
=!(E1 <= S2) && !(E2 <= S1)
= (E1 > S2)  &&  (E2 > S1)

実際、↑の条件で被る4つのケース一つ一つチェックしてみれば、すべて合ってることが分かります。もし数学が強い人がちゃんと4つの被るケースの共通点を見つければ、たぶん同じ結果になるでしょう。我々一般人にとって、同じ結果に辿り着けるには、逆思考がキーになります。

長方形の衝突検知

もうひとつ自分が興味を持っていた問題を紹介します。長方形の衝突検知。

f:id:unifa_tech:20190604113432p:plain

長方形の衝突検知はよくゲームで使われるらしいです。例えば、2つのオブジェクトがぶつかるかによってダメージを受けるかなどを決めます。

方法1

時間帯と同じ方法を使えます。金色長方形を長方形1とし、水色長方形は長方形2とする。X軸に長方形1と長方形2が被るかつY軸に長方形1と長方形2が被れば長方形1と長方形2が被る。つまり

長方形1: (x1, y1), (x2, y2)
長方形2: (x3, y3), (x4, y4)
[x1, x2] と [x3, x4] 被る -> (x2 > x3) && (x4 > x1)
[y1, y2] と [y3, y4] 被る -> (y2 > y3) && (y4 > y1)
よって衝突の条件は
(x2 > x3) && (x4 > x1) && (y2 > y3) && (y4 > y1)
方法2

↑以外に、もう一つ方法があります。2つの円が被るかどうかの条件を考えてみましょう。円でしたら中心と中心の距離が2つの円の半径の和より大きいでしたら被らない、小さいでしたら被るということになります。同じように、長方形の中心と中心のX軸の距離が2つの長方形の高さの半分より小さいかつY軸の距離も2つの長方形の幅の半分より小さいでしたら2つの長方形が被る。つまり

f:id:unifa_tech:20190604140657p:plain

長方形1: (x1, y1), (x2, y2)
長方形2: (x3, y3), (x4, y4)
w1 = (x2 - x1), h1 = (y2 - y1)
w2 = (x4 - x3), h2 = (y4 - y3)
中心1 ((x2 + x1) / 2, (y2 + y1) / 2)
中心2 ((x4 + x3) / 2, (y4 + y3) / 2)
ABSは絶対値関数
中心の距離: (
    ABS((x4 + x3) / 2 - (x2 + x1) / 2), 
    ABS((y4 + y3) / 2 - (y2 + y1) / 2)
)
衝突の条件
ABS((x4 + x3) / 2 - (x2 + x1) / 2) < (w1 + w2) / 2 && 
    ABS((y4 + y3) / 2 - (y2 + y1) / 2)) < (h1 + h2) / 2
ABS((x4 + x3) - (x2 + x1)) < (w1 + w2) && 
    ABS((y4 + y3) - (y2 + y1))) < (h1 + h2)
ABS((x4 + x3) - (x2 + x1)) < ((x2 - x1) + (x4 - x3)) && 
    ABS((y4 + y3) - (y2 + y1))) < ((y2 - y1) + (y4 - y3))

条件は2つに減りました。

方法1と方法2が同じなのかは私が答えられないですが、中心の距離で判断するのを理解すればいいと思います。

さいご

いかがでしょうか。たまにこういう数学っぽい問題を解いてみましょうか。普段の開発ではあまりこういう問題が出ないですが、気分転換としていい勉強になると思います。

Vue.jsで複数ページにまたがるフォームをVuexを使わずに実装してみる

滑り込みで東京オリンピックの抽選申し込みを済ませました、Webエンジニアの本間です。 どの日でもよいので抽選に当たって欲しいのですが、全部当たると困ってしまう、なかなか悩ましい気持ちになりました。

さて弊社では、現在開発中のプロジェクトのフロントエンドの実装において Vue.js を使っています。 今回、Vue.jsを使った実装をしている中で、複数ページにまたがるフォームの実装で調査した内容を紹介しようと思います。

続きを読む

sudo実行時のカレントディレクトリや環境変数などの挙動について

おはこんにちばんわ! ひさびさなユニファのインフラのすずきです。

最近八王子から、都心に引っ越してきました。
やはり通勤時間が短いと快適ですよね。
そして先日AWSのRe:Inventのチケット申込みが始まりましたね。
今年は行きたい…い゛ぎたい!!!!

と前置きはおいて今回は2度めのsudo関連のブログです。

前回のsudoの記事はこちら、

tech.unifa-e.com

なんかそこそこ見てもらえてるみたいで、関連記事かけという強いプレッシャーの元今回書くことにしました。

では本題

続きを読む

Core Imageをつかって画像処理はじめました

こんにちはiOSエンジニアのしだです。
写真の画像補正をiOS上でOpenCVを使って実装したらメモリの消費やCPU使用率が激しくつらい気持ちになりました。 CIFilterいいよって教えてもらって、Core Image をあまり真面目に使ったことがなかったのですが使い始めてみました。

はじめは ビルトインの CIFilter と CI Kernel Language を見ていたのですが、 CIKernel(source string: String) のAPIが非推奨になっていたため調べてみたら Metal Shading Language が使えるようになっていました。 WWDC2018によると今後はCI Kernel Language は非推奨になってくようです。

CI Kernel Language は実行時にコンパイルされるのに対して、Metal Shading のほうはアプリのビルド時にコンパイルされるのでシンタックスエラーもすぐわかるので便利です。 CIKernel 向けの Metal Shading Language を使ってみたので、いくつかサンプルを上げておきます。

続きを読む

UniFa Developer's MeetUp&LT会 #1を開催しました。

こんにちは。ユニファエンジニアの田渕です。

長かったGWも終わりましたが、みなさまどのようにお過ごしでしたでしょうか??

今日は、少々前のお話になってしまいますが、4月に開催した「UniFa Developer's MeetUp&LT会 #1」について お話していこうと思います。 合わせて、同じイベントについてPodcastでも話しておりますので、ご興味ありましたら聞いてみてください。

UniFa Developer's Podcast

続きを読む

スクラムとは何なのか?

はじめまして。認定スクラムマスター(なりたてほやほや)の渡部です。

スクラムには、必須とも言えるスクラムイベントや、定義された様々なルールが存在します。

多くの場合、まずは教科書のやり方に倣って導入されるチームがほとんどだと思います(実際、それをオススメします)が、 ただ書いてある通りに運用しているだけだと、「う〜ん、こんな場合はどうするんだっけ?」「そもそも何のためにやってるんだっけ?」「うまくいってる実感が無いけどどうすれば…」という疑問が出てくるときがあると思います。ありますよね?

そんなとき、「そもそもスクラムとは何なのか?」を理解しておくことで、最適な判断を行えるようになりますし、現状のやり方は何がイケてないのか?どうするべきなのか?を考えることができるようになります。

そこで今回は、下記2点について解説していきたいと思います。

本記事で解説する内容
  • スクラムってそもそも何なのか?
  • スクラムイベントって実のところ何をしてるの?
想定読者
  • スクラムを勉強中の方
  • スクラムを導入したが、いまいち各種イベントがしっくりこない方
  • スクラムを自分のチームなりにアレンジしたい(or アレンジしたは良いが、これで良いか分からない)方

スクラムってそもそも何?

まずスクラムガイドを参照してみると、以下のように記載されています。

複雑で変化の激しい問題に対応するためのフレームワークであり、可能な限り価値の高いプロダクトを生産的かつ創造的に届けるためのものである。

https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf

と、アジャイル開発のフレームワークの1つであることがわかりますね。

さらに読み進めていくと、スクラムの3本の柱について記載されています。
僕なりにスーパーラフに説明すると次のようになります。

スクラムの3本の柱ってなぁに?

  • 【透明性】
    • あらゆるもの・ことが見える化されてることだよ!
      タスクはもちろん、作業の進捗、プロセス、メンバーの幸福度、困ってることなど、本当にありとあらゆるものだよ!
  • 【検査】
    • 見える化されたあらゆるもの・ことをチェックすることだよ!
  • 【適応】
    • 検査されたものの中で、悪いものは良い方向に、良いものはもっと良くなるよう、変更・調整をかけることだよ!

スクラムのあらゆるイベント・ルールは上記「3本の柱」の上になりたっていますので、 一言で、スクラムとは「あらゆる作業を見える化し、問題を特定し、着実にカイゼンを積み重ねるフレームワーク」と言えます。

上記を理解せずに運用してしまうと、せっかくのイベント、1つ1つのプロセスに価値を見いだせなくなってしまうでしょう。

スクラムを行ううえでは、(スクラムマスターは特にですが)チーム全員が上記を理解することが大切です。

そして当然の事ながら、スクラムマスターはチームが上記を理解できるよう、支援をすることが必要になります。

スクラムイベントで行なっていること

この章では、スクラムイベントで行なっていることを、上記「3本の柱」に当てはめて見ていきます。
激しくラフにまとめていますが、ざっくりイメージを掴んでいただければよろしいかと思います。

そうすることで、各スクラムイベントの目的とは何なのか?何をしているのか?の理解の助けになるなぁと個人的に思っています。

また、これは経験談ですが、自分のチームなりにアレンジする際にどう調整すれば良いのかも判断しやすくなると考えています(というかなりました)。

※各イベントで具体的に何をすべきか、どうするのが良いか等は、また別の機会にお話できればと思います。

スプリントプランニング

【透明性】スプリントで成し遂げることを決定し、
【検査】成し遂げると決めたことが、確実に完了できるかを詳細に確認し、
【適応】完了を阻害する要因がある場合、確実に完了できるよう調整・変更を加える

上記を行うことで、 確実にスプリントで完了できる計画をたてることが可能となります。

デイリースクラム(朝会)

【透明性】チームで毎日集まって、やったこと、これからやること、困ってることを話し合うことで
【検査】作業の進捗、問題、他チームメンバーの作業への影響などを把握する
【適応】-

上記を行うことで、 大きな問題になる前に気付くことができたり、困っているメンバーのフォローをすることができるようになります。

※デイリースクラムの場では状況の把握までを目的としています。 問題がある場合は、デイリースクラム終了後に時間をとり、必要な人のみで議論します。

スプリントレビュー

【透明性】スプリントで完成したもののデモや、最新のスケジュールを共有することで、
【検査】関係者の適切な確認・フィードバックを得ることができ、
【適応】必要に応じて、バックログの修正やスケジュールの調整、開発計画の見直しを行う

上記を行うことで、 スプリントごとに正しい方向性を都度確認しながら、手戻りの少ない開発を進めることが可能となります。

スプリントレトロスペクティブ(ふりかえり)

【透明性】次のスプリントを始める前にチームで、人 / 関係 / プロセス / ツールの観点でふりかえることで
【検査】良かったこと・改善が必要なことを特定、整理でき、
【適応】次のスプリントで実施すべきカイゼン計画を行える

上記を行うことで、 スプリントを経るごとに、一歩ずつですが着実に生産性を向上させることが可能となります。

おわりに

上記のように、スクラムでは【透明性】【検査】【適応】の「3本の柱」がいたるところに組み込まれており、(これがまた難しいのですが、)しっかりと理解し適切に運用することができれば、着実に生産性を上げられるようになっています。

これが、スクラムで生産性が向上する秘密というか仕組みです。

  • スクラムとは何なのか?
  • スクラムイベントでは何をやっているのか?

拙い文章ではありますが、上記を理解する上での一助となれば幸いです。