Use math module trig functions for scalars

This commit replaces the use of np.sin/np.cos/np.tan uses throughout
the library with math.sin/math.cos/math.tan for scalar values
This commit is contained in:
Ogi Moore 2021-04-19 22:18:59 -07:00
parent c4a1cf11a1
commit 1138c67d45
3 changed files with 18 additions and 28 deletions

View File

@ -6,8 +6,7 @@ Distributed under MIT/X11 license. See license.txt for more information.
""" """
from .Qt import QtCore from .Qt import QtCore
from . import functions as fn from math import atan2, hypot, degrees
from math import sin, acos, atan2, inf, pi, hypot
class Point(QtCore.QPointF): class Point(QtCore.QPointF):
@ -95,23 +94,14 @@ class Point(QtCore.QPointF):
"""Returns the vector length of this Point.""" """Returns the vector length of this Point."""
return hypot(self[0], self[1]) # length return hypot(self[0], self[1]) # length
def norm(self): def norm(self):
"""Returns a vector in the same direction with unit length.""" """Returns a vector in the same direction with unit length."""
return self / self.length() return self / self.length()
def angle(self, a): def angle(self, a):
"""Returns the angle in degrees between this vector and the vector a.""" """Returns the angle in degrees between this vector and the vector a."""
n1 = self.length() rads = atan2(self.y(), self.x()) - atan2(a.y(), a.x())
n2 = a.length() return degrees(rads)
if n1 == 0. or n2 == 0.:
return None
## Probably this should be done with arctan2 instead..
ang = acos(fn.clip_scalar(self.dot(a) / (n1 * n2), -1.0, 1.0)) ### in radians
c = self.cross(a)
if c > 0:
ang *= -1.
return ang * 180. / pi
def dot(self, a): def dot(self, a):
"""Returns the dot product of a and this Point.""" """Returns the dot product of a and this Point."""
@ -129,8 +119,7 @@ class Point(QtCore.QPointF):
def __repr__(self): def __repr__(self):
return "Point(%f, %f)" % (self[0], self[1]) return "Point(%f, %f)" % (self[0], self[1])
def min(self): def min(self):
return min(self[0], self[1]) return min(self[0], self[1])

View File

@ -432,16 +432,16 @@ def makeArrowPath(headLen=20, headWidth=None, tipAngle=20, tailLen=20, tailWidth
If *tailLen* is None, no tail will be drawn. If *tailLen* is None, no tail will be drawn.
""" """
if headWidth is None: if headWidth is None:
headWidth = headLen * np.tan(tipAngle * 0.5 * np.pi/180.) headWidth = headLen * math.tan(tipAngle * 0.5 * math.pi / 180.)
path = QtGui.QPainterPath() path = QtGui.QPainterPath()
path.moveTo(0,0) path.moveTo(0,0)
path.lineTo(headLen, -headWidth) path.lineTo(headLen, -headWidth)
if tailLen is None: if tailLen is None:
innerY = headLen - headWidth * np.tan(baseAngle*np.pi/180.) innerY = headLen - headWidth * math.tan(baseAngle * math.pi / 180.)
path.lineTo(innerY, 0) path.lineTo(innerY, 0)
else: else:
tailWidth *= 0.5 tailWidth *= 0.5
innerY = headLen - (headWidth-tailWidth) * np.tan(baseAngle*np.pi/180.) innerY = headLen - (headWidth-tailWidth) * math.tan(baseAngle* math.pi / 180.)
path.lineTo(innerY, -tailWidth) path.lineTo(innerY, -tailWidth)
path.lineTo(headLen + tailLen, -tailWidth) path.lineTo(headLen + tailLen, -tailWidth)
path.lineTo(headLen + tailLen, tailWidth) path.lineTo(headLen + tailLen, tailWidth)

View File

@ -5,6 +5,7 @@ import numpy as np
from .. import Vector from .. import Vector
from .. import functions as fn from .. import functions as fn
import warnings import warnings
from math import cos, sin, tan
##Vector = QtGui.QVector3D ##Vector = QtGui.QVector3D
ShareWidget = None ShareWidget = None
@ -183,7 +184,7 @@ class GLViewWidget(QtWidgets.QOpenGLWidget):
nearClip = dist * 0.001 nearClip = dist * 0.001
farClip = dist * 1000. farClip = dist * 1000.
r = nearClip * np.tan(fov * 0.5 * np.pi / 180.) r = nearClip * tan(fov * 0.5 * np.pi / 180.)
t = r * h / w t = r * h / w
## Note that X0 and width in these equations must be the values used in viewport ## Note that X0 and width in these equations must be the values used in viewport
@ -328,9 +329,9 @@ class GLViewWidget(QtWidgets.QOpenGLWidget):
elev = self.opts['elevation'] * np.pi / 180 elev = self.opts['elevation'] * np.pi / 180
azim = self.opts['azimuth'] * np.pi / 180 azim = self.opts['azimuth'] * np.pi / 180
pos = Vector( pos = Vector(
center.x() + dist * np.cos(elev) * np.cos(azim), center.x() + dist * cos(elev) * cos(azim),
center.y() + dist * np.cos(elev) * np.sin(azim), center.y() + dist * cos(elev) * sin(azim),
center.z() + dist * np.sin(elev) center.z() + dist * sin(elev)
) )
return pos return pos
@ -387,7 +388,7 @@ class GLViewWidget(QtWidgets.QOpenGLWidget):
cPos = self.cameraPosition() cPos = self.cameraPosition()
cVec = self.opts['center'] - cPos cVec = self.opts['center'] - cPos
dist = cVec.length() ## distance from camera to center dist = cVec.length() ## distance from camera to center
xDist = dist * 2. * np.tan(0.5 * self.opts['fov'] * np.pi / 180.) ## approx. width of view at distance of center point xDist = dist * 2. * tan(0.5 * self.opts['fov'] * np.pi / 180.) ## approx. width of view at distance of center point
xScale = xDist / self.width() xScale = xDist / self.width()
zVec = QtGui.QVector3D(0,0,1) zVec = QtGui.QVector3D(0,0,1)
xVec = QtGui.QVector3D.crossProduct(zVec, cVec).normalized() xVec = QtGui.QVector3D.crossProduct(zVec, cVec).normalized()
@ -412,11 +413,11 @@ class GLViewWidget(QtWidgets.QOpenGLWidget):
azim = np.radians(self.opts['azimuth']) azim = np.radians(self.opts['azimuth'])
fov = np.radians(self.opts['fov']) fov = np.radians(self.opts['fov'])
dist = (self.opts['center'] - self.cameraPosition()).length() dist = (self.opts['center'] - self.cameraPosition()).length()
fov_factor = np.tan(fov / 2) * 2 fov_factor = tan(fov / 2) * 2
scale_factor = dist * fov_factor / self.width() scale_factor = dist * fov_factor / self.width()
z = scale_factor * np.cos(elev) * dy z = scale_factor * cos(elev) * dy
x = scale_factor * (np.sin(azim) * dx - np.sin(elev) * np.cos(azim) * dy) x = scale_factor * (sin(azim) * dx - sin(elev) * cos(azim) * dy)
y = scale_factor * (np.cos(azim) * dx + np.sin(elev) * np.sin(azim) * dy) y = scale_factor * (cos(azim) * dx + sin(elev) * sin(azim) * dy)
self.opts['center'] += QtGui.QVector3D(x, -y, z) self.opts['center'] += QtGui.QVector3D(x, -y, z)
else: else:
raise ValueError("relative argument must be global, view, or view-upright") raise ValueError("relative argument must be global, view, or view-upright")
@ -434,7 +435,7 @@ class GLViewWidget(QtWidgets.QOpenGLWidget):
dist = ((pos-cam)**2).sum(axis=-1)**0.5 dist = ((pos-cam)**2).sum(axis=-1)**0.5
else: else:
dist = (pos-cam).length() dist = (pos-cam).length()
xDist = dist * 2. * np.tan(0.5 * self.opts['fov'] * np.pi / 180.) xDist = dist * 2. * tan(0.5 * self.opts['fov'] * np.pi / 180.)
return xDist / self.width() return xDist / self.width()
def mousePressEvent(self, ev): def mousePressEvent(self, ev):