開発環境
- OS X Mavericks - Apple(OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- Python (プログラミング言語)
初めてのコンピュータサイエンス(Jennifer Campbell、Paul Gries、Jason Montojo、Greg Wilson(著)長尾 高弘(翻訳))の12章(各種ツール)、12.7(練習問題)、12-4、5.を解いてみる。
12.7(練習問題)、12-4、5.
| line1 | line2 | 出力 | 説明 |
|---|---|---|---|
| 10 | [[0, 0], [1, 1]] | ValueError | 2つの引数が浮動小数点数の対になっているか |
| [[0.0], [1, 1]] | [[1, 0], [2, 1]] | None | 線分が交わらない場合 |
| [[0, 0], [1, 1] | [[0, 1], [1, 0]] | [0.5, 0.5] | 線分が1点で交わる場合 |
| [[0, 0], [1, 1]] | [[1, 1], [2, 2]] | [1, 1] | 線分の端が接している場合 |
| [[0, 0], [1, 1]] | [[0, 0], [1, 1]] | GeometryError, [[0, 0], [1, 1]] | 一致する場合 |
| [[0, 0], [2, 2]] | [[1, 1], [3, 3]] | [[0, 0], [2, 2]] | 線分が部分的に重なり合う場合 |
コード(BBEdit)
sample.py
#!/usr/bin/env python3.3
#-*- coding: utf-8 -*-
class GeometryError(Exception):
def __str__(self):
return "GeometryError"
def lineIntersect(line1, line2):
if not (type(line1) == list and len(line1) == 2 and type(line2) == list
and len(line2) == 2):
raise ValueError("ValueError")
new_line1 = newline(line1)
new_line2 = newline(line2)
if new_line1 == new_line2:
raise GeometryError()
if new_line1[0] == new_line2[1]:
return new_line1[0]
if new_line1[1] == new_line2[0]:
return new_line1[1]
slope1 = slope(new_line1)
slope2 = slope(new_line2)
if slope1 == None and slope2 == None:
return None
if slope2 == None:
x = new_line2[0][0]
if x < new_line1[0][0] or new_line1[1][0] < x:
return None
y = slope1 * x + yIntercept(new_line1)
return [x, y]
if slope1 == None:
x = new_line1[0][0]
if x < new_line2[0][0] or new_line2[1][0] < x:
return None
y = slope2 * x + yIntercept(new_line2)
return [x, y]
y_intercept1 = yIntercept(new_line1)
y_intercept2 = yIntercept(new_line2)
if slope1 == slope2:
if y_intercept1 == y_intercept2 and \
new_line1[0][0] < new_line2[0][0] < new_line1[1][0]:
return line1
else:
return None
x = -(y_intercept1 - y_intercept2) / (slope1 - slope2)
if new_line1[0][0] <= x <= new_line1[1][0]:
y = slope1 * x + y_intercept1
y1 = min(new_line1[0][1], new_line1[1][1])
y2 = max(new_line1[0][1], new_line1[1][1])
if y1 <= y <= y2:
return [x, y]
else:
return None
def slope(line):
x1 = line[0][0]
x2 = line[1][0]
y1 = line[0][1]
y2 = line[1][1]
if y2 == y1:
return None
return (x2 - x1) / (y2 - y1)
def newline(line):
new_line = []
x1 = line[0][0]
x2 = line[1][0]
y1 = line[0][1]
y2 = line[1][1]
if x1 > x2 or (x1 == x2 and y1 > y2):
new_line = [[x2, y2], [x1, y1]]
else:
new_line = line[:]
return new_line
def yIntercept(line):
p = line[0]
x = p[0]
y = p[1]
return y - slope(line) * x
if __name__ == '__main__':
for line1, line2 in [(10, [[0, 0], [1, 1]]),
([[0, 0], [1, 1]], [[1, 0], [2, 1]]),
([[0, 0], [1, 1]], [[0, 1], [1, 0]]),
([[0, 0], [1, 1]], [[1, 1], [2, 2]]),
([[0, 0], [1, 1]], [[0, 0], [1, 1]]),
([[0, 0], [2, 2]], [[1, 1], [3, 3]])]:
try:
print(lineIntersect(line1, line2))
except ValueError as err:
print(err)
except GeometryError as err:
print(err)
except Exception as err:
print(err)
入出力結果(Terminal)
$ ./sample.py ValueError None [0.5, 0.5] [1, 1] GeometryError [[0, 0], [2, 2]] $
0 コメント:
コメントを投稿