Last active
July 14, 2016 08:12
-
-
Save sungyongchoi/a1ee9184167dec1d8387921ec116207b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#python 3.x | |
import matplotlib.pyplot as plt | |
import matplotlib.mlab as mlab | |
import matplotlib.cbook as cbook | |
import numpy as np | |
import matplotlib.pyplot as plt | |
from matplotlib.widgets import Button, Cursor | |
import tkinter as Tk | |
from tkinter import filedialog | |
import os | |
import csv | |
import math | |
import matplotlib.path as mpath | |
import matplotlib.patches as mpatches | |
from types import * | |
import struct | |
from struct import unpack | |
import numpy as np | |
import binascii | |
import functools | |
import sys | |
from mpmath import mp | |
def hextodouble(value): | |
bytes = list( map(ord,reversed(value)) ) | |
sign = (1,-1)[bytes[0]>>7] | |
exp = ((0x7f&bytes[0])<<4) + (bytes[1]>>4) - 1023 | |
mantissa = functools.reduce(lambda x,y: (x<<8) + y, bytes[2:], bytes[1]&0xf) | |
return sign*2**exp*( 1+ mp.mpf( mantissa )*2**-52 ) | |
class Point: | |
def __init__(self, x=0 ,y=0 ): | |
self.x = x | |
self.y = y | |
def Distance(self, target): | |
xDelta = target.x - self.x | |
yDelta = target.y - self.y | |
if xDelta == 0 and yDelta == 0 : | |
print(" p1 and p2 cannot be the same point " ) | |
return math.sqrt ( ( xDelta ) ** 2 + ( yDelta )**2 ) | |
def rotate_vector(v, angle, anchor): | |
"""Rotate a vector `v` by the given angle, relative to the anchor point.""" | |
x, y = v | |
x = float(x) - anchor[0] | |
y = float(y) - anchor[1] | |
# Here is a compiler optimization; inplace operators are slower than | |
# non-inplace operators like above. This function gets used a lot, so | |
# performance is critical. | |
cos_theta = math.cos(math.radians(angle)) | |
sin_theta = math.sin(math.radians(angle)) | |
nx = x*cos_theta - y*sin_theta | |
ny = x*sin_theta + y*cos_theta | |
nx = nx + anchor[0] | |
ny = ny + anchor[1] | |
return [nx, ny] | |
def angle (p1, p2, p0): | |
#http://stackoverflow.com/questions/2827393/angles-between-two-n-dimensional-vectors-in-python | |
v0 = np.array(p0) - np.array(p1) | |
v1 = np.array(p2) - np.array(p1) | |
angle = np.math.atan2( np.linalg.det( [v0,v1] ), np.dot(v0,v1) ) | |
return np.degrees(angle) | |
# http://paulbourke.net/geometry/pointlineplane/source.c | |
def DistancePointLine( LineStart, LineEnd, P ): | |
LineMag = LineStart.Distance( LineEnd ) | |
U = ( ( ( P.x - LineStart.x ) * ( LineEnd.x - LineStart.x ) ) + | |
( ( P.y - LineStart.y ) * ( LineEnd.y - LineStart.y ) ) ) / ( LineMag ** 2 ) | |
if( U < 0.0 or U > 1.0 ): | |
print ( "closest point does not fall within the line segment") | |
return | |
InterSection = Point ( ) | |
InterSection.x = LineStart.x + U * ( LineEnd.x - LineStart.x ) | |
InterSection.y = LineStart.y + U * ( LineEnd.y - LineStart.y ) | |
#draw line and point | |
ax.plot( LineStart.x, LineStart.y, 'o') | |
ax.plot( LineEnd.x, LineEnd.y, 'o') | |
ax.plot( P.x, P.y, 'o') | |
ax.plot( [LineStart.x, LineEnd.x], [LineStart.y, LineEnd.y], '-') | |
ax.plot( [InterSection.x, P.x], [InterSection.y, P.y], '-') | |
mx=(InterSection.x+P.x)/2 | |
my=(InterSection.y+P.y)/2 | |
bbox_props = dict( fc="cyan", ec="b", lw=2) | |
t = ax.text(mx, my, str( P.Distance( InterSection ) ), | |
ha="center", va="center", rotation=0, | |
size=15, | |
bbox=bbox_props) | |
''' | |
ax.annotate ( str( P.Distance( InterSection ) ), xy=(mx,my), | |
xytext=(P.x-1 , P.y/2), | |
arrowprops=dict(arrowstyle="->"), | |
) | |
''' | |
plt.draw() | |
return | |
class Viewer(object): | |
def __init__(self, scat, x, y): | |
self.x = x | |
self.y = y | |
self.counter = 0 | |
self.cid = 0 | |
self.cid1 = 0 | |
self.Points = [] | |
axrotate = plt.axes([0.7, 0.05, 0.1, 0.075]) | |
brotate = Button(axrotate, 'Rotate') | |
axheight = plt.axes([0.81, 0.05, 0.1, 0.075]) | |
bheight = Button(axheight, 'Distance') | |
self._widgets=[brotate,bheight] | |
brotate.on_clicked(self.rotate) | |
bheight.on_clicked(self.height) | |
def rotate( self, event ): | |
self.cid=fig.canvas.mpl_connect('button_press_event', self.onpick1) | |
def height( self, event ): | |
self.cid1=fig.canvas.mpl_connect('button_press_event', self.onpick2) | |
def onpick1( self, event ): | |
self.counter += 1 | |
idx=(np.abs(self.x-event.xdata)).argmin() # get array index after click | |
xpos = self.x [ idx ] | |
idx=(np.abs(self.y-event.ydata)).argmin() | |
ypos = self.y [ idx ] | |
p = Point() | |
p.x = xpos | |
p.y = ypos | |
self.Points.append ( p ) | |
if (self. counter % 2) == 0: | |
p1 = ( float(self.Points[0].x), float(self.Points[0].y) ) # if float() is nothing, err occurs in angle function | |
p0 = ( float(self.Points[1].x), float(self.Points[1].y) ) | |
p2 = ( float(self.Points[1].x), float(self.Points[0].y) ) | |
ang = angle (p1, p2, p0) | |
anchor = ( 0, 0 ) | |
l=len(xs) | |
self.x = [] | |
self.y = [] | |
for i in range(l): | |
v = ( xs[i], ys[i] ) | |
rotateV= rotate_vector ( v, ang, anchor ) | |
self.x.append( float(rotateV[0]) ) # rotate x | |
self.y.append( float(rotateV[1]) ) # rotate z | |
ax.clear() | |
scat1 = ax.scatter ( self.x, self.y) | |
plt.draw() | |
self.counter = 0 | |
self.Points = [] | |
fig.canvas.mpl_disconnect(self.cid) | |
def onpick2( self, event ): | |
self.counter += 1 | |
#idx=(np.abs(self.x-event.xdata)).argmin() | |
x, y = event.xdata, event.ydata | |
idx = np.searchsorted(self.x, [x])[0] | |
xpos = self.x [ idx ] | |
#idx=(np.abs(self.y-event.ydata)).argmin() | |
ypos = self.y [ idx ] | |
p = Point() | |
p.x = xpos | |
p.y = ypos | |
self.Points.append ( p ) | |
if (self. counter % 3) == 0: | |
i = self.counter - 3 | |
j = self.counter - 2 | |
k = self.counter -1 | |
DistancePointLine( self.Points[ i ], self.Points[ j ], self.Points[ k ] ) | |
fig.canvas.mpl_disconnect(self.cid) | |
if __name__ == '__main__': | |
folder = filedialog.askopenfilename() | |
file = open(folder, 'rb') | |
file.seek(0x4EC) | |
rows = file.read(2) | |
rows = int.from_bytes(rows,'little') | |
file.seek(0x4708) | |
total = rows << 4 # rows x 16 | |
points = file.read( total ) | |
file.close() | |
xs = [] | |
ys = [] | |
for r in range( rows*2 ): # rows*2 means X, Y | |
p= [] | |
for c in range( 8 ): | |
i=8*r+c | |
s = points[i] | |
b = bytes([s]) # Convert byte to int | |
p.append ( b ) | |
if (c == 7) : | |
if (r%2 == 0) : | |
xs.append( hextodouble ( p ) ) | |
else: | |
ys.append( hextodouble ( p ) ) | |
fig, ax = plt.subplots() | |
plt.subplots_adjust(bottom=0.2) | |
scat = ax.scatter(xs, ys) | |
ax.grid( ) | |
Viewer( scat, xs, ys ) | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment