Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sungyongchoi/a1ee9184167dec1d8387921ec116207b to your computer and use it in GitHub Desktop.
Save sungyongchoi/a1ee9184167dec1d8387921ec116207b to your computer and use it in GitHub Desktop.
#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