所以我有一个问题,我有一个长度的数组(通常很长)。我有一个初始启动索引到该数组和跳过值。所以,如果我有这个:
var initial = 5;
var skip = 10;
然后我用索引5,15,25,35等迭代我的数组。 但是我可能会得到一个新的起始值,我需要找到最接近初始值的值加上或减去跳过的倍数然后开始跳过。因此,如果我的新值是23,那么我将迭代25,35,45等。
我的算法是:
index = (round((start - initial) / skip) * skip) + initial
然后我需要检查索引是否已降至零以下:
while(index < 0) index += skip;
所以我的第一个问题是,是否有这个名字?随机启动的倍数? 我的第二个问题是,如果有更好的方法吗?我不认为我所拥有的是非常复杂的,但如果我错过了一些我想知道的东西。
如果重要的是我使用javascript。
谢谢!
答案 0 :(得分:1)
修改的
而不是
import random
import sys
import IPython
from OCC.Display.qtDisplay import qtViewer3d, get_qt_modules
from OCC.gp import gp_Pnt2d, gp_Pnt
from OCC.BRepBuilderAPI import (BRepBuilderAPI_MakeEdge,
BRepBuilderAPI_MakeVertex,
BRepBuilderAPI_MakeWire)
from OCC.BRepFill import BRepFill_Filling
from OCC.GeomAbs import GeomAbs_C0
from OCC.GeomAPI import GeomAPI_PointsToBSpline
from OCC.TColgp import TColgp_Array1OfPnt
QtCore, QtGui, QtOpenGL = get_qt_modules()
try:
from OpenGL.GL import (glViewport, glMatrixMode, glOrtho, glLoadIdentity,
GL_PROJECTION, GL_MODELVIEW)
except ImportError:
msg = "for this example, the OpenGL module is required" \
"why not run \"pip install PyOpenGL\"\?"
sys.exit(status=1)
class GLWidget(qtViewer3d):
def __init__(self, parent=None):
super(GLWidget, self).__init__(parent)
self._initialized = False
midnight = QtCore.QTime(0, 0, 0)
random.seed(midnight.secsTo(QtCore.QTime.currentTime()))
self.object = 0
self.xRot = 0
self.yRot = 0
self.zRot = 0
self.image = QtGui.QImage()
self.bubbles = []
self.lastPos = QtCore.QPoint()
self.lines = []
self.current_point = None
self.pts = []
self.shiftHeld = True
self.trolltechGreen = QtGui.QColor.fromCmykF(0.40, 0.0, 1.0, 0.0)
self.trolltechPurple = QtGui.QColor.fromCmykF(0.39, 0.39, 0.0, 0.0)
self.animationTimer = QtCore.QTimer()
self.animationTimer.setSingleShot(False)
self.animationTimer.timeout.connect(self.animate)
self.animationTimer.start(25)
self.setAutoFillBackground(False)
self.setMinimumSize(200, 200)
self.setWindowTitle("Overpainting a Scene")
# parameters for overpainting
self.setAttribute(QtCore.Qt.WA_NoSystemBackground, 0)
self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
def setXRotation(self, angle):
if angle != self.xRot:
self.xRot = angle
def setYRotation(self, angle):
if angle != self.yRot:
self.yRot = angle
def setZRotation(self, angle):
if angle != self.zRot:
self.zRot = angle
def mousePressEvent(self, event):
self.lastPos = event.pos()
super(GLWidget, self).mousePressEvent(event)
worldCoords = super(GLWidget, self).mapToGlobal( self.lastPos )
print self.lastPos
if event.buttons() & QtCore.Qt.RightButton and not (event.modifiers() & QtCore.Qt.ShiftModifier):
print 'first'
self.pts.append(gp_Pnt(self.lastPos.x(), self.lastPos.y(), 0.0))
elif event.buttons() & QtCore.Qt.RightButton and (event.modifiers() & QtCore.Qt.ShiftModifier):
print 'second'
curve = self.points_to_bspline(self.pts)
self._display.DisplayShape(curve, update=True)
self.pts = [] #clear it
def mouseMoveEvent(self, event):
dx = event.x() - self.lastPos.x()
dy = event.y() - self.lastPos.y()
"""
if (event.buttons() & QtCore.Qt.LeftButton):
self.setXRotation(self.xRot + 8 * dy)
self.setYRotation(self.yRot + 8 * dx)
elif (event.buttons() & QtCore.Qt.RightButton):
self.setXRotation(self.xRot + 8 * dy)
self.setZRotation(self.zRot + 8 * dx)
"""
self.lastPos = event.pos()
super(GLWidget, self).mouseMoveEvent(event)
def paintGL(self):
if self._inited:
self._display.Context.UpdateCurrentViewer()
def paintEvent(self, event):
if self._inited:
self._display.Context.UpdateCurrentViewer()
self.makeCurrent()
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
if self.context().isValid():
self.swapBuffers()
if self._drawbox:
painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0), 1))
rect = QtCore.QRect(*self._drawbox)
painter.drawRect(rect)
"""
for bubble in self.bubbles:
if bubble.rect().intersects(QtCore.QRectF(event.rect())):
bubble.drawBubble(painter)
"""
painter.end()
self.doneCurrent()
else:
print('invalid OpenGL context: Qt cannot overpaint viewer')
def showEvent(self, event):
pass
#self.createBubbles(20 - len(self.bubbles))
def sizeHint(self):
return QtCore.QSize(400, 400)
def animate(self):
pass
"""
for bubble in self.bubbles:
bubble.move(self.rect())
self.update()
"""
def setupViewport(self, width, height):
side = min(width, height)
glViewport((width - side) // 2, (height - side) // 2, side, side)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
glMatrixMode(GL_MODELVIEW)
def points_to_bspline(self, pnts):
pts = TColgp_Array1OfPnt(0, len(pnts)-1)
for n, i in enumerate(pnts):
pts.SetValue(n, i)
crv = GeomAPI_PointsToBSpline(pts)
return crv.Curve()
if __name__ == '__main__':
def TestOverPainting():
class AppFrame(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setWindowTitle(self.tr("qtDisplay3d overpainting example"))
self.resize(640, 480)
self.canva = GLWidget(self)
mainLayout = QtGui.QHBoxLayout()
mainLayout.addWidget(self.canva)
mainLayout.setContentsMargins(0, 0, 0, 0)
self.setLayout(mainLayout)
def runTests(self):
self.canva._display.Test()
app = QtGui.QApplication(sys.argv)
frame = AppFrame()
frame.show()
frame.canva.InitDriver()
frame.runTests()
app.exec_()
TestOverPainting()
如果我们假设初始和跳过都是肯定的,您可以使用:
while(index < 0) index += skip;
答案 1 :(得分:1)
不需要while
循环:
function newNum(newstart, initial, skip) {
var xLow = newstart + Math.abs(newstart - initial) % skip;
var xHi = newstart + skip;
var result = (xLow + xHi) / 2 > newstart ? xLow : xHi;
if (result < 0) result += skip;
return result;
}
获取新起点和初始值之间的距离,并找出如果你朝着那个初始值行进的剩余部分(模数给我们的话)。然后你只需要找出最近点是在起点之前还是之后(我这样做是将低值和高值的中点与起点进行比较)。
测试:
newNum(1, 20, 7) = 6
newNum(-1, 20, 7) = 6
newNum(180, 10, 3) = 182
(即使你在评论中说明新起点的范围在数组范围内,请注意它并不重要)。
答案 2 :(得分:1)
要获得number
与test number
的最接近倍数:查看modulo
的{{1}}是否大于test number
,如果是,返回number/2
:
number - modulo
要检查某个数字是否是另一个数字的倍数,请将其模数与0进行比较:
function closestMultiple(multipleTest,number)
{
var modulo = multipleTest%number;
if(0 == modulo )
{
return multipleTest;
}
else
{
var halfNumber = number/2;
if(modulo >= halfNumber)
{
return multipleTest + (number-modulo);
}
else
{
return multipleTest - modulo;
}
}
}
您可能希望为0添加一些验证,以防您有任何内部最近的多个。
答案 3 :(得分:1)
index
的值,按照你的计算
index = round((start - initial)/skip) * skip + initial
确实是最小化序列与通用术语
之间距离的那个 j = j * skip + initial
和start
。
因此,如果index
位于
start
只能是否定的
(a -1 + a 0 )/ 2 = initial - skip/2
换句话说,如果
start < initial - skip/2.
因此,只有在这种情况下,您才需要将index
重新定义为0
。在伪代码中:
IF (start < (initial - skip/2))
index = 0
ELSE
index = round((start - initial)/skip) * skip + initial
或者,您可以
index = round((start - initial)/skip) * skip + initial
IF index < 0 THEN index = 0
是一样的。