Difference in behavior in OpenSCAD between % and # - debugging

Using OpenSCAD 2019.05 on Mac OS 10.15.7,
difference() {
cube(size = [14, 24, 17], center = false);
% cube(size = [10, 20, 17], center = false);
}
fails (sometimes with the familiar "No geometry" error, sometimes with a cube with no subtraction).
However, with only the substition of # for %, the expected behavior is produced. Am I misunderstanding the semantics of # and %?
(As you'd expect, I didn't write the code this way, I took CSG output from my original program and boiled it down to this example.)

I used to get confused by them too. % allows you to put things in the F5 preview of the model that will not show up in the actual render with F6. See https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Modifier_Characters#Background_Modifier
"Ignore this subtree for the normal rendering process and draw it in transparent gray (all transformations are still applied to the nodes in this tree)."
So, the line with % is being ignored when you render it and it should result in the first cube being rendered unmodified.

Related

function-like interpolation in React Native?

I have a scrollview with fixed length in my RN project that should act like a parralax scroll behavior. When I scroll and move the Y component, the X component of the header is moving right so when it is on top, it is 56 pixels away from the left edge, leaving enough place for the back arrow.
But it is linear. Is there a way to make it exponential. The best example would be the WhatsApp contact's parralax scroll:
Watch the Title "Dune"
How I have it now = red line (linear)
How I would like to = blue line (linear with easing, exponential, whatever it's called)
I got the scaling animation done, but the linear motion is like a thorn in my eye and the documentation for Animated values is overwhelming and unclear a bit.
I've defined:
scrollY: new Animated.Value(0)
in state and in my scrollview like this:
<ScrollView
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: this.state.scrollY}}}]
)}
and my Animated.View inside of it looks like this:
<Animated.View
style={[
{marginTop: 30, alignSelf: 'flex-start' },
{translateX: headerTranslateX}
]}]}>
<Text>Title</Text>
</Animated.View>
Aand the interpolation:
const titleTranslateX = this.state.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE*0.6, HEADER_SCROLL_DISTANCE],
outputRange: [0, 0, 56],
extrapolate: 'clamp',
})
which is linear in nature (i tried setting 10+keypoints in inputRange and outputRange bit but it gets messy and doesn't look natural enough)
Any advice on how to achieve the desired effect?
The only thing it says in the Animated docs on easing (function interpolation) is:
Interpolation
Each property can be run through an interpolation first. An interpolation maps input ranges to output ranges, typically using a linear interpolation but also supports easing functions. By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value.
It doesn't mention how you can add an easing function. However, in the source code you'll find this: https://github.com/facebook/react-native/blob/e2ce98b7c6f4f2fc7011c214f9edc1301ff30572/Libraries/Animated/src/Interpolation.js#L27
export type InterpolationConfigType = {
inputRange: Array<number>,
/* $FlowFixMe(>=0.38.0 site=react_native_fb,react_native_oss) - Flow error
* detected during the deployment of v0.38.0. To see the error, remove this
* comment and run flow
*/
outputRange: (Array<number> | Array<string>),
easing?: ((input: number) => number),
extrapolate?: ExtrapolateType,
extrapolateLeft?: ExtrapolateType,
extrapolateRight?: ExtrapolateType,
};
The easing function defaults to linear (t) => t, but you can make it any standard easing function. Here's a nice list: https://gist.github.com/gre/1650294
Note: this won't work if you're using useNativeDriver: true.
Hope this helps reduce the choppiness!

Why doesn't Synth.new understand about scales?

I can set a scale like this:
~pp = Scale.phrygian(\pythagorean);
I can then create a Pbind which plays the scale like this:
(
Pbind(
*[
instrument: \default,
scale: ~pp,
degree: Pseq([0, 1, 2, 3, 4, 5, 6, 7], inf),
amp: 0.5,
dur: 0.5
]
).play;
)
But Synth.new doesn't seem to get it at all (just results in silence):
b = Synth.new(\default, [\scale: ~pp, \degree: 3, \amp, 0.5]);
Interestingly, if I remove the scale parameter:
b = Synth.new(\default, [\degree: 3, \amp, 0.5]);
then I get a note, but it's always the same note. It doesn't respond to the degree parameter.
Ultimately, I would like to be able to trigger notes from an external OSC device (my phone!). This means hooking up OSCFunc to listen out for certain triggers, and play notes from a scale when those OSC events occur. I thought I could use Synth.new inside OSCFunc to actually play the notes, but it doesn't seem to know about scales, so I'm a bit stuck.
Can anyone provide any advice about how to acheive this?
Have a good read of the Pattern Guide, in particular Pattern Guide 07: Value Conversions. It's a good tutorial. It will tell you that these magical conversions are not used everywhere in SuperCollider, but only when you use Event-based scheduling such as Patterns (e.g. your Pbind). The value conversions are actually defined in "the default Event", as described further in that tutorial article.
One consequence of all of this is that, if you want to launch just one note but you still want value conversions, you can do it with the Event style of playing notes, which creates an event using () and then calls .play on it:
~synth = (instrument: \default, scale: [0,2,4,5,7,9,11], degree: 12.rand, amp: 0.5).play;
~synth = (instrument: \default, scale: [0,3,6,9], degree: 12.rand, amp: 0.5).play;
This still returns a Synth object.
See the Event helpfile for more on this way of doing it.

Print image to pdf without margin using Matlab

I'm trying to use the answers I found in these questions:
How to save a plot into a PDF file without a large margin around
Get rid of the white space around matlab figure's pdf output
External source
to print a matlab plot to pdf without having the white margins included.
However using this code:
function saveTightFigure( h, outfilename, orientation )
% SAVETIGHTFIGURE(H,OUTFILENAME) Saves figure H in file OUTFILENAME without
% the white space around it.
%
% by ``a grad student"
% http://tipstrickshowtos.blogspot.com/2010/08/how-to-get-rid-of-white-margin-in.html
% get the current axes
ax = get(h, 'CurrentAxes');
% make it tight
ti = get(ax,'TightInset');
set(ax,'Position',[ti(1) ti(2) 1-ti(3)-ti(1) 1-ti(4)-ti(2)]);
% adjust the papersize
set(ax,'units','centimeters');
pos = get(ax,'Position');
ti = get(ax,'TightInset');
set(h, 'PaperUnits','centimeters');
set(h, 'PaperSize', [pos(3)+ti(1)+ti(3) pos(4)+ti(2)+ti(4)]);
set(h, 'PaperPositionMode', 'manual');
set(h, 'PaperPosition',[0 0 pos(3)+ti(1)+ti(3) pos(4)+ti(2)+ti(4)]);
% save it
%saveas(h,outfilename);
if( orientation == 1)
orient portrait
else
orient landscape
end
print( '-dpdf', outfilename );
end
Results in this output:
As you can see the 'PaperSize' seems to be set not properly. Any idea of possible fixes?
NOTE
If I change the orientation between landscape and portrait the result is the same, simply the image is chopped in a different way.
However if I save the image with the saveas(h,outfilename); instruction the correct output is produced.
Why is this? And what is the difference between the two saving instructions?
Alltogether the answers you mentioned offer a lot of approaches, but most of them didn't worked for me neither. Most of them screw up your papersize when you want to get the tight inset, the only which worked for me was:
set(axes_handle,'LooseInset',get(axes_handle,'TightInset'));
I finally wrote a function, where I specify the exact height and width of the output figure on paper, and the margin I want (or just set it to zero). Be aware that you also need to pass the axis handle. Maybe this functions works for you also.
function saveFigure( fig_handle, axes_handle, name , height , width , margin)
set(axes_handle,'LooseInset',get(axes_handle,'TightInset'));
set(fig_handle, 'Units','centimeters','PaperUnits','centimeters')
% the last two parameters of 'Position' define the figure size
set(fig_handle,'Position',[-margin -margin width height],...
'PaperPosition',[0 0 width+margin height+margin],...
'PaperSize',[width+margin height+margin],...
'PaperPositionMode','auto',...
'InvertHardcopy', 'on',...
'Renderer','painters'... %recommended if there are no alphamaps
);
saveas(fig_handle,name,'pdf')
end
Edit: if you use painters as renderer saveas and print should produce similar results. For jpegs print is preferable as you can specify the resolution.

Creating THREE.Line's with different endpoints using THREE.BufferGeometry

I am creating several THREE.Lines using THREE.BufferGeometry. Initially my app had them all starting at the origin and things worked as expected. Now, I would like to be able to start (and end) them at any point.
This fiddle (http://jsfiddle.net/9nVqU/) illustrates (I hope) how changing one end of the line away from the origin causes unexpected results.
I wondered if it was because any given line follows on from the previous one - switching the start/end order didn't change anything though so if that were true, I'd expect it to break.
Maybe I have the arrays set up incorrectly or the attributes that tell THREE.js how to interpret it - I think I need 2 * 3 verts for each line but changes I made to buffer_geometry.attributes = { seemed to make things worse.
FWIW, the actual effect I'm trying to achieve is to selectively turn on and off the lines based on user input. I can do that already by changing the end position but then I lose that value and I don't want to store it elsewhere. I thought that I could move the start point to the end point to switch it off and then move the start point to the origin again to re-enable it. If there is a way to enable/disable lines individually with BufferGeometry, then that would clearly be better.
First of all, you would have to do this:
var line = new THREE.Line( buffer_geometry, material );
line.type = THREE.LinePieces;
Second, this is not supported in r.58 , but should be.
As a work-around, you can hack WebGLRenderer.renderBufferDirect() like so:
// render lines
setLineWidth( material.linewidth );
var position = geometryAttributes[ "position" ];
primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
_gl.drawArrays( primitives, 0, position.numItems / 3 );
_this.info.render.calls ++;
_this.info.render.points += position.numItems;
three.js r.58

In Matplotlib, how do you add an Imagedraw object to a PyPlot?

I need to add a shape to a preexisting image generated using a pyplot (plt). The best way I know of to generate basic shapes quickly is using Imagedraw's predefined shapes. The original data has points with corresponding colors in line_holder and colorholder. I need to add a bounding box (or in this case ellipse) to the plot to make it obvious to the user whether the data is in an acceptable range.
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
from PIL import Image
...
lines = LineCollection(mpl.line_holder, colors=mpl.colorholder , linestyle='solid')
plt.axes().add_collection(lines)
plt.axes().set_aspect('equal', 'datalim')
plt.axes().autoscale_view(True,True,True)
plt.draw()
plt.show()
I tried inserting this before the show():
image = Image.new('1',(int(ceil(disc/conv))+2,int(ceil(disc/conv))+1), 1)
draw = ImageDraw.Draw(image)
box=(1, 1, int(ceil(disc/conv)), int(ceil(disc/conv))) #create bounding box
draw.ellipse(box, 1, 0) #draw circle in black
but I cannot find a way to then add this ellipse to the pyplot. Does anyone know how one would go about getting the images together? If it is not possible to add an imagedraw object to a pyplot, are there good alternatives for performing this type of operation?
Matplotlib has several patches (shapes) that appear to meet your needs (and remove PIL as a dependency). They are documented here. A helpful example using shapes is here.
To add an ellipse to a plot, you first create a Ellipse patch and then add that patch to the axes you're currently working on. Beware that Circle's (or Ellipse's with equal minor radii) will appear elliptical if your aspect ratio is not equal.
In your snippet you call plt.axes() several times. This is unnecessary, as it is just returning the current axes object. I think it is clearer to keep the axes object and directly operate on it rather than repeatedly getting the same object via plt.axes(). As far as axes() is used in your snippet, gca() does the same thing. The end of my script demonstrates this.
I've also replaced your add_collection() line by a plotting a single line. These essentially do the same thing and allows my snippet to be executed as a standalone script.
import matplotlib.pyplot as plt
import matplotlib as mpl
# set up your axes object
ax = plt.axes()
ax.set_aspect('equal', 'datalim')
ax.autoscale_view(True, True, True)
# adding a LineCollection is equivalent to plotting a line
# this will run as a stand alone script
x = range(10)
plt.plot( x, x, 'x-')
# add and ellipse to the axes
c = mpl.patches.Ellipse( (5, 5), 1, 6, angle=45)
ax.add_patch(c)
# you can get the current axes a few ways
ax2 = plt.axes()
c2 = mpl.patches.Ellipse( (7, 7), 1, 6, angle=-45, color='green')
ax2.add_patch(c2)
ax3 = plt.gca()
c3 = mpl.patches.Ellipse( (0, 2), 3, 3, color='black')
ax3.add_patch(c3)
print id(ax), id(ax2), id(ax3)
plt.show()

Resources