IText: how to draw image over a line (both on a PdfTemplate) - itext

I have defined a chart-panel-template, which owns a graph-template and other stuff.
The graph-template shows both x-y-axis and also the measurement points. At the end I wrapp this chartpanel-template in an image object, and then add it to document object.
Problem is: I want to connect the measurement point setting a dot-image on each point. I am unable to put the dot-image on the connecting lines. Lines go through the dots. This is a part of my code:
while(iter.hasNext()){
key= iter.next();
value= (int) this.getDataset().get(key);
y= (int)(value * this.getyConversionRatio() + getXAxisHeight());
ColumnText.showTextAligned(this.templateContent, Element.ALIGN_LEFT,new Paragraph(String.valueOf(value), this.font), x, y+ getDotIamge().getHeight()*2, 0);
if(i==0){
this.templateContent.moveTo(x + getDotIamge().getWidth()/2, y + getDotIamge().getHeight()/2);
}else{
this.templateContent.lineTo(x + getDotIamge().getWidth()/2, y + getDotIamge().getHeight()/2);
}
//this.templateContent.stroke(); // this call doesn't draw any lines at all.
getDotIamge().setAbsolutePosition(x, y);
this.templateContent.addImage(getDotIamge());
i++;
x= x+ this.getxScaleStepLength();
}
//this.templateContent.stroke(); // this call draw the lines as expected over the dots.
I want the dots to be drawn over the lines. What shall I take into consideration?
Thanks in advance.

Related

Getting angle between line and x-axis(horizontal top of screen)

I have created a basic program which draws shapes using graphics context. A line object holds its own start and end points. I wish to use the first quadrant values that are standard when building in java.
I have tried to create Point2D objects which gave me incorrect values. Also I have tried arctan2 and arctan which return the same value no matter which line I pass them. I cannot find my mistake whether it is my code or my math. Any suggestions will be appreciated.
double slope = (this.getEndY() - this.getyCoordinate()) / (this.getEndX() - this.getxCoordinate());
return MyLine.description + Math.toDegrees(Math.atan(slope));
this is using the Point2D with three points:
Point2D point = new Point2D(1, 0); // x- axis
Point2D point1 = new Point2D(this.getxCoordinate(),this.getyCoordinate()); //p1(0,0)
Point2D point2 = new Point2D(this.endX,this.getEndY());//p2(bottom right corner of window)
double angle = point1.angle(point, point2);
return MyLine.description + " " + angle;
The first attempt is the solution I found on the site already which returns NaN.
The second is an attemp to us the Point2d API which returns 0.0.
I am expecting it to read 45.0.

How do I rotate a 3D spectrum-Image in Digital Micrograph by scripting?

I want to find the equivalent of the rotate(image, degree) script command to rotate around the x or y axis (I only need 90ยบ rotations). I know I can do it using the tool menu but it would be much faster if I could find a command or a function to do it using a script.
Thank you in advance!
Using the Slice command can be confusing at first, so here is a
detailed explanation on using the command for a rotation around the
X-axis.
This example shows how one would rotate a 3D data clockwise around its X axis (viewing along X) using the Slice3 command.
The Slice3 command specifies a new view onto an existing data array.
It first specifies the origin pixel, i.e. the coordinates (in the original data) which will be represented by (0,0,0) in the new view.
It then specifes the sampling direction, length and stepsize for each of its new three axes. The first triplet specifies how the coordinates (in the original data) change along the new image's x-direction, the second triplet for the new images's y-direction and the last triplet for the new image's z-direction.
So a rotation around the x-axis can be imagined as:
For the "resampled" data:
The new (rotated) data has it's origin at the original's data point (0,0,SZ-1).
Its X-direction remains the same, i.e. one step in X in the new data, would increment the coordinate triplet in the original's data also by (1,0,0).And one goes SX steps with a step-size of 1.
Its Y-direction is essentially the negative Z-direction from before, i.e. one step in Y in the new data, would increment the coordinate triplet in the original's data also by (0,0,-1).So one goes SZ steps with a step-size of -1.
Its Z-direction is essentially the Y-direction from before, i.e. one step in Z in the new data, would increment the coordinate triplet in the original's data by (0,1,0).So one goes SY steps with a step-size of 1.
So, for a clockwise rotation around the X-axis, the command is:
img.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 )
This command will just create a new view onto the same data (i.e. no addtional memory is used.) So to get the rotated image as a new image (with data values aligned as they should be in memory), one would clone this view into a new image usign ImageClone()
In total, the following script shows this as an example:
// Demo of rotating 3D data orthogonally around the X axis
// This is done by resampling the data using the Slice3 command
// Creation of test image with regcognizeable pattern
number SX = 100
number SY = 30
number SZ = 50
image img := RealImage("Test",4, SX,SY,SZ)
// trig. modulated linear increase in X
img = icol/iwidth* sin( icol/(iwidth-1) * 5 * Pi() ) **2
// Simple linear increase in Y
img += (irow/iheight) * 2
// Modulation of values in Z
// (doubling values for index 0,1, 3, 4, 9, 16, 25, 36, 49)
img *= (SQRT(iplane) == trunc(SQRT(iplane)) ? 2 : 1 )
img.ShowImage()
// Show captions. Image coordinate system is
// Origin (0,0,0) in top-left-front most pixel
// X axis goes left to right
// Y axis goes top to down
// Z axis goes front to back
img.ImageSetDimensionCalibration(0,0,1,"orig X",0)
img.ImageSetDimensionCalibration(1,0,1,"orig Y",0)
img.ImageSetDimensionCalibration(2,0,1,"orig Z",0)
img.ImageGetImageDisplay(0).ImageDisplaySetCaptionOn(1)
// Rotation around X axis, clockwise looking along X
// X --> X` (unchanged)
// Y --> Z'
// Z --> -Y'
// old origin moves to bottom-left-front most
// This means for "new" sampling:
// Specify sampling starting point:
// New origin (0,0,0)' will be value which was at (0,0,SZ-1)
// Going one step in X' in the new data, will be like going one step in X
// Going one step in Y' in the new data, will be like going one step backwards in Z
// Going one step in Z' in the new data, will be like going one step in Y
image rotXCW := img.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 ).ImageClone()
rotXCW.SetName("rotated X, CW")
rotXCW.ShowImage()
rotXCW.ImageGetImageDisplay(0).ImageDisplaySetCaptionOn(1)
The following methods perform 90degree rotations:
// Functions for 90degree rotations of data
image RotateXCW( image input )
{
number SX,SY,SZ
input.Get3DSize(SX,SY,SZ)
return input.Slice3( 0,0,SZ-1, 0,SX,1, 2,SZ,-1, 1,SY,1 ).ImageClone()
}
image RotateXCCW( image input )
{
number SX,SY,SZ
input.Get3DSize(SX,SY,SZ)
return input.Slice3( 0,SY-1,0, 0,SX,1, 2,SZ,1, 1,SY,-1 ).ImageClone()
}
image RotateYCW( image input )
{
number SX,SY,SZ
input.Get3DSize(SX,SY,SZ)
return input.Slice3( SX-1,0,0, 2,SZ,1, 1,SY,1, 0,SX,-1 ).ImageClone()
}
image RotateYCCW( image input )
{
number SX,SY,SZ
input.Get3DSize(SX,SY,SZ)
return input.Slice3( 0,0,SZ-1, 2,SZ,-1, 1,SY,1, 0,SX,1 ).ImageClone()
}
image RotateZCW( image input )
{
number SX,SY,SZ
input.Get3DSize(SX,SY,SZ)
return input.Slice3( 0,SY-1,0, 1,SY,-1, 0,SX,1, 2,SZ,1 ).ImageClone()
}
image RotateZCCW( image input )
{
number SX,SY,SZ
input.Get3DSize(SX,SY,SZ)
return input.Slice3( SX-1,0,0, 1,SY,1, 0,SX,-1, 2,SZ,1 ).ImageClone()
}
Rotations around the z-axis could als be done with RotateRight() and RotateLeft(). Note, however, that these commands will not adapt the images' dimension calibrations, while the Slice3 command will.
For pure orthogonal rotation the easiest (and fastest) way is to use the'slice' commands, i.e. 'slice3' for 3D images.
It turns out that the latest version of GMS has an example of it in the help documention, so I'm just copy-pasting the code here:
number sx = 10
number sy = 10
number sz = 10
number csx, csy, csz
image img3D := RealImage( "3D", 4, sx, sy, sz )
img3D = 1000 + sin( 2*PI() * iplane/(idepth-1) ) * 100 + icol * 10 + irow
img3D.ShowImage()
// Rotate existing image
if ( OKCancelDialog( "Rotate clockwise (each plane)\n= Rotate block around z-axis" ) )
img3D.RotateRight()
if ( OKCancelDialog( "Rotate counter-clockwise (each plane)\n= Rotate block around z-axis" ) )
img3D.RotateLeft()
if ( OKCancelDialog( "Rotate block counter-clockwise around X-axis" ) )
{
// Equivalent of sampling the data anew
// x-axis remains
// y- and z-axis change their role
img3D.Get3DSize( csx, csy, csz ) // current size along axes
img3D = img3D.Slice3( 0,0,0, 0,csx,1, 2,csz,1, 1,csy,1 )
}
if ( OKCancelDialog( "Rotate block clockwise around X-axis" ) )
{
// Equivalent of sampling the data anew
// x-axis remains
// y- and z-axis change their role
img3D.Get3DSize( csx, csy, csz ) // current size along axes
img3D = img3D.Slice3( 0,csy-1,csz-1, 0,csx,1, 2,csz,-1, 1,csy,-1 )
}
if ( OKCancelDialog( "Rotate 30 degree (each plane)\n= Rotate block around z-axis" ) )
{
number aDeg = 30
number interpolMeth = 2
number keepSize = 1
image rotImg := img3D.Rotate( 2*Pi()/360 * aDeg, interpolMeth, keepSize )
rotImg.ShowImage()
}
You may also want to look at this answer for some more info on subsampling and creating differnt views on data.

unable to draw a line correctly using hough transformation in matlab

I used this code for drawing lines using Hough tranform. In this code, there is a draw of the image in Polar space . I want to draw detected lines in Cartesian space. Thus, with the help of this explanation I wrote my code like this:
imBinary = flipud(edge(rgb2gray(im),'sobel'));
[imWidth,imLenght]=size(imBinary);
[interestPointY , interestPointX] = find(imBinary);
numberOfInterestingPoints=numel(interestPointX);
maxRadius=sqrt(imWidth^2 + imLenght^2);
polarRadius=(-maxRadius:1:maxRadius);
polarTheta=(-pi/2:(1/200):pi/2);
numberOfPolarThetas=numel(polarTheta);
houghMatrix=zeros(numel(polarRadius),numberOfPolarThetas);
polarAccumulator = zeros(numberOfInterestingPoints,numberOfPolarThetas);
cosine = (0:imWidth-1)'*cos(polarTheta);
sine = (0:imLenght-1)'*sin(polarTheta);
polarAccumulator((1:numberOfInterestingPoints),:) =cosine(interestPointY,:) + sine(interestPointX,:);
for i = (1:numberOfPolarThetas)
houghMatrix(:,i) = hist(polarAccumulator(:,i),polarRadius);
end
radiusDetect=[];angleDetect=[];
houghBinaryMax = imregionalmax(houghMatrix);
[Potential_radius ,Potential_angle] = find(houghBinaryMax == 1);
%[radiusIndex angleIndex] = find(houghMatrix > 0);
houghTmp= houghMatrix - lineThreshold;
for cnt = 1:numel(Potential_radius)
if houghTmp(Potential_radius(cnt),Potential_angle(cnt)) >= 0
radiusDetect = [radiusDetect;Potential_radius(cnt)];
angleDetect = [angleDetect;Potential_angle(cnt)];
end
end
radius=polarRadius(radiusDetect);
deg=polarTheta(angleDetect);
%find two points in cartesian space
x=radius.*cos(deg);
y=radius.*sin(deg);
x1=x+5.*cos(deg);
y1=y+5.*cos(deg);
imshow(imBinary);
hold on;
plot([x x1],[y y1]);
Unfortunately I did not get the correct lines and my image in like this:the blue lines are detected
My question is what the mistake is that I cannot draw lines correctly?

finding the intersection of a line with a non monotonic arbitrary surface?

I have a surface Z on a X-Y grid for which I want to find the intersection point with a line. I used so far this code for finding the intersection:
x_ray = x_source + t * x_dir
y_ray = y_source + t * y_dir
z_ray = z_source + t * z_dir
height_above_plane = #(t) z_source + t * z_dir - interp2(X, Y, Z, ...
x_source + t*x_dir, y_source + t*y_dir)
t_intercept = fzero(height_above_plane, 0);
my problem is that when my surface is "wiggly", the function has several zero crossing points, and I want to find the minimal out of them.
How can I do that?
Thanks
A possible approach is to project the ray onto the XY domain and draw the corresponding Bresenham line. As you go along this line, grid cell per grid cell, you will compute the Z altitudes along the ray and check if their range overlaps the range of altitudes of the surface (i.e. the min and max value in this cell).
If yes, you have to find the 3D intersection between the ray and the interpolating surface, an hyperbolic paraboloid. If the intersection does fall inside the grid cell considered, you are done. Otherwise, continue the march along the ray.
Convert the surface to matlab mesh, then use this code.

Draw 2 imline to be perpendicular to each other matlab

Is there any way to constraint the the imline to be always perpendicular to the other imline drawn on the same object. for ex. I draw a first line using "imline" now I want to draw second line across the first line to be perpendicular to it. if there is a way to force the second imline to be perpendicular to the first line keeping the flexibility of extending the length it will solve my problem some extent.
I want something like a flexible cross hair(which can rotate along the axis and have flexible sides) on my image to measure the height and width of the certain object.
Code:
function perpline()
imshow(rand(200),[]);
line1 = imline(gca,[50 50; 150 150]);
setColor(line1,'r');
line2 = imline(gca,[50 150; 150 50]);
setColor(line2,'g');
addNewPositionCallback(line2,#(pos)callback_line(pos));
function callback_line(pos)
% Must update line1 based on line2's position
pos_line1 = getPosition(line1);
pos_line2 = getPosition(line2);
% Get middle
pos_center = [(pos_line2(1,1)+pos_line2(2,1))/2 (pos_line2(1,2)+pos_line2(2,2))/2];
% Find displacement
vec_disp = [pos_line2(2,1)-pos_line2(1,1) pos_line2(2,2)-pos_line2(1,2)];
% Get normal unit vector
vec_perp = [-vec_disp(2) vec_disp(1)]/norm(vec_disp);
% Preserve length of line2
length_line1 = norm([pos_line1(2,1)-pos_line1(1,1) pos_line1(2,2)-pos_line1(1,2)]);
pos_line1_update = [-vec_perp*length_line1/2+pos_center;
vec_perp*length_line1/2+pos_center];
% Set position
setPosition(line1,pos_line1_update);
end
end
Save it as a function then call it. You can drag the green line around and the red line remains perpendicular. Note that you have to define how you want it to preserve the perpendicularity. I chose to preserve the length of the red line and keep it in the center of the green line.