Say I generated a dots = psychopy.visual.DotStim. Is it possible to change the number of dots later? dots.nDots = 5 leads to an error on the next dots.draw() because the underlying matrices don't match:
Traceback (most recent call last):
File "/home/jonas/Documents/projects/work pggcs/experiment/dots.py", line 32, in <module>
dots_right.draw()
File "/usr/lib/python2.7/dist-packages/psychopy/visual/dot.py", line 279, in draw
self._update_dotsXY()
File "/usr/lib/python2.7/dist-packages/psychopy/visual/dot.py", line 362, in _update_dotsXY
self._verticesBase[:,0] += self.speed*numpy.reshape(numpy.cos(self._dotsDir),(self.nDots,))
File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 218, in reshape
return reshape(newshape, order=order)
ValueError: total size of new array must be unchanged
The same is true of psychopy.visual.ElementArrayStim for which setting stim.nElements = 5 similarly results in an error on the next draw.
A solution is of course to instantiate a whole new DotStim or ElementArrayStim every time the number of dots/elements should change but this seems too heavy.
It can be fixed for the DotStim:
dots.nDots = 5
dots._dotsDir = [0]*dots.nDots
dots. _verticesBase = dots._newDotsXY(dots.nDots)
This set movement of all dots to 0 but you can change that value to whatever you like or specify for individual dots. This is a hack which will likely break if you modify other aspects of the DotStim.
I haven't figured out a solution for ElementArrayStim.
Yes, it would be nice to be able to do this but I haven't gotten around to it. The code that has to be run when the nDots/nElements changes is pretty close to starting from scratch with a new stimulus.init so adding this in 'correctly' probably means some refactoring (move a lot of the init code into setNDots() and then call it from init).
There's an additional potential issue which is that the elements might have changed (e.g. the user has set the orientations) and then updates the number of elements. Which ones do we remove? And what orientation do we give those that we add? (This is less of an issue for DotStim though)
Basically, the issue is a little thorny and hasn't ben a priority for me.
Related
Basically, I have rewritten code that kept giving me a segmentation fault (core dump) error when running, and I decided to check each step to rule out issues.
My code works, until I try accessing/using the last line of the input files data. I do the same things to this line as to the line previous, but it's suggesting somethings wrong.
Here is my code for the file I/O and data handling:
The input file itself is simply:
20 20
10 10 u
5 5 d
In line 27, you dereference the uninitialised playerDirInput, which is undefined behaviour:
playerDir = (char)playerDirInput[0];
That's probably the cause of your crash. If that code block is meant to mirror the following one, it looks like you just haven't read the third item on that line, which is where playerDirInput is probably meant to come from. That would be something like:
fgets(line, 8, f);
playerRowChar = strtok(line, " ");
playerRow = atoi(playerRowChar);
playerColChar = strtok(NULL, " "); // <- fixed this, see below.
playerCol = atoi(playerColChar);
playerDirInput = strtok(NULL, " "); // <- add this.
playerDir = (char)playerDirInput[0];
However, I would suggest you instead opt for the simpler sscanf version, which would go something like (including a check to ensure you get the three items):
fgets(line, 8, f);
if (sscanf(line, "%d %d %c", &playerRow, &playerCol, &playerDir) != 3) {
handleErrorIntelligently();
}
I tend to prefer fgets followed by sscanf, rather than fscanf. The latter can fail in such a way that you're not sure where the input stream pointer ends up as. With fgets, you always know you've read a line (or can easily detect that you read a partial line and adjust for it).
Other potential problems you should look at:
On line 25, this strtok should be of the NULL type, not line. The latter will simply re-read the first item on that line wheras you want the next item.
You really should check functions that can return problematic values (such as NULL from strtok). Otherwise, using them can cause issues. That depends on the data you're reading, of course, so may not necessarily be a problem if you control that.
I am seeking a solution of connecting all the lines that have the same slope and share a common point. For example, after I load a STL file and cut it using a plane, the cutter output includes the points defining the contour. Connecting them one by one forms a (or multiple) polyline. However, some lines can be merged when their slopes are the same and they share a common point. E.g., [[0,0,0],[0,0,1]] and [[0,0,1],[0,0,2]] can be represented by one single line [[0,0,0],[0,0,2]].
I wrote a function that can analyse all the lines and connect them if they can be merged. But when the number of lines are huge, this process is slow. I am thinking in the VTK pipeline, is there a way to do the line merging?
Cheers!
plane = vtk.vtkPlane()
plane.SetOrigin([0,0,5])
plane.SetNormal([0,0,1])
cutter = vtk.vtkCutter()
cutter.SetCutFunction(plane)
cutter.SetInput(triangleFilter.GetOutput())
cutter.Update()
cutStrips = vtk.vtkStripper()
cutStrips.SetInputConnection(cutter.GetOutputPort())
cutStrips.Update()
cleanDataFilter = vtk.vtkCleanPolyData()
cleanDataFilter.AddInput(cutStrips.GetOutput())
cleanDataFilter.Update()
cleanData = cleanDataFilter.GetOutput()
print cleanData.GetPoint(0)
print cleanData.GetPoint(1)
print cleanData.GetPoint(2)
print cleanData.GetPoint(3)
print cleanData.GetPoint(4)
The output is:
(0.0, 0.0, 5.0)
(5.0, 0.0, 5.0)
(10.0, 0.0, 5.0)
(10.0, 5.0, 5.0)
(10.0, 10.0, 5.0)
Connect the above points one by one will form a polyline representing the cut result. As we can see, the line [point0, point1] and [point1, point2] can be merged.
Below is the code for merging the lines:
Assume that the LINES are represented by list: [[(p0),(p1)],[(p1),(p2)],[(p2),(p3)],...]
appended = 0
CurrentLine = LINES[0]
CurrentConnectedLine = CurrentLine
tempLineCollection = LINES[1:len(LINES)]
while True:
for HL in tempLineCollection:
QCoreApplication.processEvents()
if checkParallelAndConnect(CurrentConnectedLine, HL):
appended = 1
LINES.remove(HL)
CurrentConnectedLine = ConnectLines(CurrentConnectedLine, HL)
processedPool.append(CurrentConnectedLine)
if len(tempLineCollection) == 1:
processedPool.append(tempLineCollection[0])
LINES.remove(CurrentLine)
if len(LINES) >= 2:
CurrentLine = LINES[0]
CurrentConnectedLine = CurrentLine
tempLineCollection = LINES[1:len(LINES)]
appended = 0
else:
break
Solution:
I figured out a way of further accelerating this process using some vtk data structure. I found out that a polyline line will be stored in a cell, which can be checked by using GetCellType(). Since the point order for a polyline is sorted already, We do not need to search globally which lines are colinear with the current one. For each point on the polyline, I just need to check the point[i-1], point[i], point[i+1]. And if they are colinear, the end of the line will be updated to the next point. This process continues until the end of the polyline is reached. The speed increases by a huge amount compared with the global search approach.
Not sure if it is the main source of slowness (depends on how many positive hits on the colinearity you have), but removing items from a vector is costly (O(n)), since it requires reorganizing the rest of the vector, you should avoid it. But even without hits on colinearity, the LINES.remove(CurrentLine) call is surely slowing things down and there isn't really any need for it - just leave the vector untouched, write the final results to a new vector (processedPool) and get rid of the LINES vector in the end. You can modify your algorithm by making a bool array (vector), initialized at "false" for each item, then when you remove a line, you don't actually remove it, but only mark it as "true" and you skip all lines for which you have "true", i.e. something like this (I don't speak python so the syntax is not accurate):
wasRemoved = bool vector of the size of LINES initialized at false for each entry
for CurrentLineIndex = 0; CurrentLineIndex < sizeof(LINES); CurrentLineIndex++
if (wasRemoved[CurrentLineIndex])
continue // skip a segment that was already removed
CurrentConnectedLine = LINES[CurrentLineIndex]
for HLIndex = CurrentLineIndex + 1; HLIndex < sizeof(LINES); HLIndex++:
if (wasRemoved[HLIndex])
continue;
HL = LINES[HLIndex]
QCoreApplication.processEvents()
if checkParallelAndConnect(CurrentConnectedLine, HL):
wasRemoved[HLIndex] = true
CurrentConnectedLine = ConnectLines(CurrentConnectedLine, HL)
processedPool.append(CurrentConnectedLine)
wasRemoved[CurrentLineIndex] = true // this is technically not needed since you won't go back in the vector anyway
LINES = processedPool
BTW, the really correct data structure for LINES to use for that kind of algorithm would be a linked list, since then you would have O(1) complexity for removal and you wouldn't need the boolean array. But a quick googling showed that that's not how lists are implemented in Python, also don't know if it would not interfere with other parts of your program. Alternatively, using a set might make it faster (though I would expect times similar to my "bool array" solution), see python 2.7 set and list remove time complexity
If this does not do the trick, I suggest you measure times of individual parts of the program to find the bottleneck.
I have a program written in vb.net that creates a graph and draws various lines on it parsed from an XML file. Each line defines if points on the graph must be above or below it.
Simply put, I am looking for a way to find the closest number ABOVE and BELOW a certain point.
So say we have a straight line {(0,0)(1,1)(2,2)(3,3)}
and a point we want to validate (1.5,4) Say this point needs to be ABOVE the line.
Also, i should mention that the line may not always be a straight line but have many segments representing a curve.
I suspect the easiest way to do this is to find the 2 points on the line surrounding our point on the x axis, get the slope between them and then interpolate.
So I tried this:
pointBelow = validationLine.points.Aggregate(Function(x, y) If(Math.Abs(x.X - paramPoint.XValue) < Math.Abs(y.X - paramPoint.YValues(0)), x, y))
pointAbove = validationLine.points.Aggregate(Function(x, y) If(Math.Abs(x.X - paramPoint.XValue) < Math.Abs(y.X - paramPoint.YValues(0)), x, y))
As you can see, these will obviously both return the same value, so I would like to know how I can search for the closest number in a list BELOW a given value, then do the same thing but search ABOVE that value.
P.S. it is also possible that the point we are validating may be at the exact same place on the x axis as one of the vertices on our line and I am looking for a solution that will solve this regardless.
Sorry but it's too long to comment.
It depends on the line that you are comparing it to... if your line is a function, it means it will never 'go backwards', and you just have to compare the Y-values of the point and your line at point X.
If it's not a function, then it's harder, and maybe you should ask that question on a math Q&A site, like https://mathematica.stackexchange.com/
I'm trying to create a line with a different fill and stroke color, something like this:
I have tried the following:
Line line = new Line(0,0,100,100);
line.setFill(Color.RED);
line.setStroke(Color.BLACK);
line.setStrokeWidth(10);
but this gives me just a black line.
Is what I'm trying to do possible with a simple Line or do I have to use another Shape? (I would prefer using a line because I have to frequently call the setStartX, setStartY, ... methods)
If you check this question, you'll see that you can only use setStroke. Also, a possible approach to generate the same styling is proposed by using a linear gradiant.
This will work (adjust stops at your convenience for more or less black width):
Line line = new Line(0,0,100,0);
line.setStrokeWidth(10);
line.setStroke(new LinearGradient(0d, -5d, 0d, 5d, false,
CycleMethod.NO_CYCLE, new Stop(0,Color.BLACK),
new Stop(0.199,Color.BLACK),
new Stop(0.2,Color.RED),
new Stop(0.799,Color.RED),
new Stop(0.8,Color.BLACK)));
Note also that since the gradient is not proportional, you need to use rotation to generate not horizontal lines.
The answer of José Pereda is more elegant but I couldn't get the math right to create diagonal lines so as a workaround I simply created two lines, each with a different color:
Line stroke = new Line(0, 0, 100, 100);
Line fill = new Line(0, 0, 100, 100);
stroke.setStrokeWidth(10);
fill.setStrokeWidth(8);
stroke.setStroke(Color.BLACK);
fill.setStroke(Color.RED);
pane.addAll(stroke, fill);
No math required and I can keep on using the setStartX,setStartY, ... methods of the lines although I now have double the amount of lines.
I'm really new to programming Objective-C and programming in general, so forgive me if this is a super obvious question:
I'm wondering if Objective-C runs code line by line. What I mean by that is if it processes one line before moving onto another, or if it just runs the next line regardless of whether the previous line is finished or not.
For example,
int difference = number1 - number2;
if (difference < 0) {
difference = difference + 10;
}
result = difference;
Say that number1 = 3 and number2 = 7. When I run this code, will it go line by line and run the if block before line 5 and give me result = 6, or will it start running the if block and line 5 at the same time and give me result = -4?
Thanks in advance!
EDIT: Changed modulo to addition because of Obj-C quirk.
As far as your thinking goes you may as well assume that it runs line by line.
In fact the compiler may put the code into a more efficient order (i.e. making sure that divisions aren't too close together, as this could make things slow). However even when the compiler does re-order things it makes sure that a result is calculated before it is needed. When you build the code in a fully optimised fashion (release mode) if you debug it you can see that the code has actually been re-ordered (the debugger jumps when you wouldn't expect it to). However as far as thinking about your code goes it's safe to assume that it runs it in the order you write it.
If you are new to programming, all programming languages you will meet at the beginning of your learning will execute statements sequentially. It means that the next one happens only after the previous one ends. However, languages like Objective C are not line-oriented and what matters are not lines but statements, like assignment ending with semicolon! or if statement.