I have an application that displays leave and absences using an Infragistics UltraMonthViewMulti user interface control.
I have several type of absences that have different colours. I have successfully created a draw filter that shows a half day triangle on the appropriate day using the following code.
If (day.Date.CompareTo(DateTime.Today) = 0) Then
drawParams.Graphics.DrawImageUnscaledAndClipped(Image.FromFile("..//..//redTriangleHalfDay.png"), day.Rect)
Return False
End If
The above code requires a PNG file in the appropriate color in the project. I would like to create these colored images dynamically in code and avoid having a large number of PNG files.
Is this possible?
Any help or suggestions greatly appreciated.
James O'Doherty
Maybe another solution for your task (using again DrawFilter) could be if you replace your images with another type of symbols/colors. Instead of drawing images, you could draw triangle, cirlces, lines, arcs and so on, if you are using for example:
Graphics gr = ultraMonthViewMulti1.CreateGraphics;;
gr.DrawPolygon(new Pen(Color.Red), new Point[] { new Point(10, 10), new Point(20, 20), new Point(10, 30), new Point(10, 10) });
By this way (using three points) you could draw a triangle. Also you could use other draw methods. For example:
gr.DrawCurve, gr.DrawEllipse, gr.DrawLine, gr.DrawPie
Feel free to write me if you have any questions
Related
I am exploring using a GAS script to build a human-readable product catalogue as a Google Spreadsheet, it's easy to generate a PDF or print from there. The product data is all quickly accessible via an API including image URLs for each product.
I'm running into issues because inserting an image which references a URL, then re-sizing it takes 3-4 seconds in my prototype, and I might have 150x products. Runtime is capped at 6 minutes. Here's a simplified example of the image processing loop that I'm imagining:
function insertImages(sheet, array_of_urls) {
for (var i in array_of_urls) {
let image = sheet.insertImage(list_of_urls[i], 1, (i+1)*3);
image.setWidth(90);
image.setHeight(90);
}
}
I think it takes so long because of the interaction with the UI. Can anyone recommend a way that I could make the script functionally efficient?
Insert images over cells:
If you want the images over cells (that is, not contained in a specific cell), I don't think there's a way to make this significantly faster. There's no method to insert multiple images at once.
You could at most try to retrieve the image blobs, resize the images through some third party before inserting them, and finally insert them via insertImage(blobSource, column, row).
In any case, there are ways to get through the 6 minute execution time limit. See, for example, this answer.
Insert image in cells:
If you don't have a problem having the images in specific cells, and not over cells, I'd suggest adding the images via IMAGE formula, using setFormulas.
The image size can be set through the IMAGE formula, the following way:
=IMAGE("URL", 4, [height in pixels], [width in pixels])
Also, to make sure the cells' height is large enough for the images to be seen, you can use setRowHeights.
Code snippet:
function insertImages(sheet, array_of_urls) {
const formulas = array_of_urls.map(url => ["=IMAGE(\"" + url + "\", 4, 90, 90)"]);
const firstRow = 1;
sheet.getRange(firstRow,1,formulas.length,formulas[0].length).setFormulas(formulas);
sheet.setRowHeights(firstRow, formulas.length, 90);
}
Before question,I seached many places, I find some similar idea but without my solution.And my question can be also described as how to recalculate the model's uv to fix the panorama designed for six faces skybox.
Recently,I came upon a unique way to get fluent 3D roaming experience on matterport's Official network https://matterport.com/gallery/
I just want to know how did they do that?Their product is very fluent when swich the panorama picture.
After I roaming many times,I found the secret. I realized that the panorama carrier they use is not box or sphere,but is the object they show first!The evidence is that when switch the point,the object such as chair and table would have their own shadow(one chair have two image one stand up and the other one lie on the floor
With the object in panorama paste on their own correspond object and with depth information the roaming switch become more fluent (As for why they do not use the object directly ,I think because of the limited hardware,Many irregularity faces which get from scanning equipment cannot be use directly
And I want to use this idea in my project ,I have a group of six panorama which can paste on a boxGeometry perfectly,and I just want to paste them on model.but I stuck in project 360 degree.Yes I just find how to project one direction but I cannot project the remaining five.
var _p=BufferGeometry.attributes;
for (var i = 0; i < _p.position.count; i++){
var uvtempbeforeconvert= ( new THREE.Vector3(_p.position.array[3*i],_p.position.array[3*i+1],_p.position.array[3*i+2]) ).clone().applyMatrix4(houseObject.matrixWorld).project(camera1)
//use the worldvertices to get its screen coordinate
if(uvtempbeforeconvert.x<1&&uvtempbeforeconvert.x>-1 && uvtempbeforeconvert.y<1 &&uvtempbeforeconvert.y>-1) {
VerticesArray1.push(_p.position.array[3*i],_p.position.array[3*i+1],_p.position.array[3*i+2]);uvArray1.push(uvtempbeforeconvert.x*0.5+0.5,uvtempbeforeconvert.y*0.5+0.5);
Yes,I success in calculating one direction.BUT I cant deal with the triangle faces which occupy two more view frustum,like a face at the edge of the box.
How should I deal with this problem?Or I run in the FALSE direction at first?Which direction should i run in ?
After asking many people,I just find that I need to usd shadermaterial in threejs ,and use a function named cubetexture,samplercube.With that I can get the pixel color what I need!
I have one problem with InputPoint.face method in Sketchup Ruby API.
When i import one image object and then draw 5-edges polygon on this image. I used InputPoint.face for getting number of edges in the polygon after clicking on it. I think the output is 5, but actually, the output is 4
If i remove the image , result will be 5.
I don't understand why the output is like that, and what can i do to get output 5?
This is my code
# The onLButtonDOwn method is called when the user presses the left mouse button.
def onLButtonDown(flags, x, y, view)
#ip = view.inputpoint x,y
#f = #ip.face
aEdges = #f.edges
puts aEdges.length
end
Thanks you
So you have drawn pentagon faces on the Image entity you imported? And when you use InputPoint to click on one of the pentagons you get a face with four edges?
What happens here is probably that you are getting the Face inside the Image entity. Under the hood an Image entity is a special component instance. You can in fact find the definition for the Image entity in model.definitions.
For more details on SketchUp and Components, Groups and Images read this article: http://www.thomthom.net/thoughts/2012/02/definitions-and-instances-in-sketchup/
InputPoint and PickHelper seem to let you pick the face inside the Image entity instead of stopping when it hits the Image entity.
You will probably want to filter out your results before using them and you probably wantto use the PickHelper class instead of InputPoint.
http://www.sketchup.com/intl/en/developer/docs/ourdoc/pickhelper.php
http://www.thomthom.net/thoughts/2013/01/pickhelper-a-visual-guide/
InputPoint is more for getting 3d points for inference, while PickHelper is best to use to pick and select entities.
You can check the Face entity you get from InputPoint and it's parent to verify which face it is and what context it belongs to.
Is it possible to output images so that they all will be inside a single window?
Before, I used to output data using only opencv functions:
cvNamedWindow("Image 1");
cvShowImage("Image 1", img);
So I change image, then call: cvShowImage function and so on.
But If I want to look at more than one image, then every new image needs its own window to be shown there And what I want is to put every such an output opencv's window inside one big main window.
Is it possible to do it? And how?
You will have to construct a new image and place each img into it. I don't think there's a builtin function like MATLAB's subplot. I recommend using the ROI functions to quickly copy an image into a region-of-interest (ROI) of the big image (which holds the others).
You can show as many images as you want on a single window using hconcat function.
Let us suppose your original image was
Mat frame;
Now clone or make a copy of this image using
Mat frame1 = frame.clone();//or
Mat frame2;
frame.copyTo(frame1);
Now let us suppose your output images are
Mat img1,img2,img3,img4;
Now if you want to show images horizontally, use
hconcat(img1,img2,frame1)//hconcat(input_image1,input_image2,destination_image);
And if you want to show images vertically, use
frame2.push_back(img1);//main_image.push_back(image_to_be_shown_below);
This process processess images one at a time, so if you want to show 4 images side by side, you have to call this function 4 times as in
hconcat(img1,img2,frame1);
hconcat(frame1,img3,frame1);
hconcat(frame1,img4,frame1);
imshow("Final Image",frame1);
NOTE:
Clone process is done because the images have to be of same size.
Enjoy...
I am making a GUI for a program I have created, where I need to be able to change the position of a load along a beam. I have set up the axes and the slider properly, but I am unsure how to get the axes to update, as I can't find any examples that show how to do this on the internet.
At present, as I move the load, the position updates properly, but the old position stays on screen as well, which is quite annoying.
Can anyone recommend any good examples that show how to do this, or does anyone have a suggestion of how to go about refreshing the axes?
Here is the slider callback (I haven't included the create_fcn function). Also, theres a lot of comments in the code, as I used the Guide function to make the GUI.
Please note that the input to slider is a proportion of the overall beam length (as a decimal).
function PointLoadxx1posslider_Callback(hObject, eventdata, handles)
% hObject handle to PointLoadxx1posslider (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
PLxx1pos = get(handles.PointLoadxx1posslider,'value');
set(handles.PLxx1posedit, 'String', num2str(PLxx1pos));
l = 3000; % This is the Length of the beam
zpl1 = get(handles.PointLoadxx1posslider,'value')*l;
% Multiplies the position decimal by the overall length
LoadPlotter(hObject,zpl1,handles) % Sends the command to the plot plot function
guidata(hObject,handles);
function LoadPlotter(hObject,zpl1,handles)
% The following draws the beam supports as lines
SH = l/20; %Height of supports
line([0 l], [SH/2 SH/2])
line([-SH/2 SH/2], [0 0])
line([-SH/2 0], [0 SH/2])
line([0 SH/2], [SH/2 0])
line([l-SH/2 l+SH/2], [0 0])
line([l-SH/2 l], [0 SH/2])
line([l l+SH/2], [SH/2 0])
xlim([ -100 l+200])
ylim([-l/2 l/2])
%Draw Load position
% zpl1 = get(handles.PointLoadxx1posslider,'value')*l;
% zpl1 = 0.5*l;
zpl2 = 0.2*l;
PL1 = 50;
%This is the value of the point load applied to the beam, which will
be an input from another slider
PL1Draw = line([zpl1 zpl1],[SH/2 PL1*10]);
% refresh(handles.axes1);
guidata(hObject,handles);
Obviously, I would like to keep the other lines drawn, but change PL1Draw as the slider is moved. Please can you explain what I am supposed to tag to do this?
Many thanks in advance.
James
I assume that you have plotted a beam, which is supposed to bend as you change the slider value. Since you are able to plot the new position into the axes, I assume that you know how to write callbacks. I further assume that there are parts of the plot that should stay the same, and parts that should change.
To change the parts that need changing, the easiest method is just to delete them and then to redraw. In order to delete specific items from a plot, it's best to tag them. Thus, your plotting would go like this
%# remove the old position
%# find the handle to the old position by searching among all the handles of
%# the graphics objects that have been plotted into the axes
oldPosHandle = findall(handles.axes1,'Tag','position');
delete(oldPosHandle);
%# plot new position
PL1Draw = line([zpl1 zpl1],[SH/2 PL1*10]);
%# add the tag so that you can find it if you want to delete it
set(PL1Draw,'Tag','position');
Note 1
To make the GUI respond faster (if needed), do not delete and re-plot, but change the 'XData' and 'YData' property of the old position object.
Note 2
If you aren't already doing so, put the plotting function (the one that updates everything in the plot, not just the position of the load) in a separate function, not into the callback of the slider, and have instead the slider callback call the plot function. This way, you can call the same plotting function from several buttons and sliders, which makes the code a lot easier to maintain.
EDIT
I have updated the commands. Note that there is no special 'tagging' function. 'Tag' is a property of every graphics object, like 'Units', or 'Color'. It simply helps you to label the graphics objects so that you don't need to remember the handles.
Unrelated to the actual question, but related to the project:
http://www.mathworks.com/matlabcentral/fileexchange/2170
This book is still available used on Amazon, it might save you a lot of the coding of the Mechanics of Materials stuff. I wrote this about 12 years ago as an undergrad, but I think the MATLAB code should still be functional.