Algorithm to enlarge/scale/inflate/enbiggen a triangle - geometry

I'm looking for an algorithm to make a triangle larger by a given scaling factor. If I multiply the 3 coordinates by the scaling factor, and the triangle is not centred on the origin, then the triangle will also translate as well as scale which is not the required effect.
The triangle needs to grow while remaining in the same place.
My initial thought would be to find the triangle centre, offset the triangle to the origin, scale, offset back again. However there's presumably a more efficient way than this?
Also, if this is the only way to do it, what's the most appropriate way of finding the centre of the triangle?

The center of the triangle should be at
(x1 + x2 + x3) / 3, (y1 + y2 + y3) / 3

using this algorithm to generate new coordinates will work well
X_new = X_cg + (X_old-X_cg)*Scale
Y_new = Y_cg + (Y_old-Y_cg)*Scale
X_cg is the geometric center of your geometry

Once you have the center point, you can do this:
Calculate the distance from one of the points of the triangle to the center, in a vector. Ie. (3,4).
Double those values (or triple, whatever you want). Ie. (6,8)
Plot the new point in comparison to the center. Ie. if the center was (1,2), you would add the new point to that and get (7,10)
Repeat for the other points of the triangle
This should work :)
To work out the center, I would work out the difference from the highest point to the lowest, halve that, and add it to the lowest (so you have the middle of those two), and then repeat for left and right. That should give you the center.

Related

In geometry nodes how can I align instances to both a curve and ground plane?

Given this simple setup:
Node Tree
Viewport Preview
How can I align the planes instances such that the y axis of each plane is parallel to the curve, and the x axis of the planes are parallel to the ground plane (x and Y axis)?
I've tried various combinations with "Align Eular to Vector" node, but as soon as the curve does not face a specific axis the planes get tilted and the alignment to ground plane is lost.
any suggestions?
So after some research I found a solution to my own question. I'm posting it in case anyone else needs to find this out.
Note that I'm not a mathematician and there might be a shorter solution (or specific nodes that I'm not aware of that can perform some of the steps). Also note that this is a solution for instances on a straight line which is what I was aiming for, I didn't test this setup on a curved line but my guess is that it will not work.
For that you'll need to perform step 3 for every point or something like that.
Ok here we go:
Generate instances on a line with the instance on point node.
Auto orient the instances on the z axis with the align Euler to vector node based on the normal of the line.
Calculate a vector between 2 points on the line (which point is not important since the line is straight but the order of the subtraction does!). To calculate the vector from point 1 to point 2 you'll have to subtract point 1 from point 2 (like so: point 2 - point 1).
Calculate the angle between the new vector and the vector of the ground plane [0,0,1]. to do that use this formula:
θ = arccosine ( dot product/ ( length(v1) * length(v2) ) ).
Calculate the complementary angle which is 90 degrees - θ
*** convert 90 to radians of course
rotate the instances on x axis by the result value.
Node Tree
Result
If there is a shorter/easier solution, let me know.

Finding pixels inside an ellipse

My maths skills are terrible so I don't even know where to start with this. This is for a hobby project written in C#.
To keep things simple, let's say I need to operate on all of the pixels positioned inside an ellipse. How would I get an array of the valid pixel locations inside the ellipse that I need to work with?
For that task i would recommend taking a look at bresenhams filled circle Algorithm.
If you scale the y achsis you can use it to draw ellipses, too.
Bresenham algorithms work by using only integer arithmetic, which makes them fast(est)
This works only for axe-parallel ellipses
In an ellipse the sum of the distance between a point in the ellipse and both foci is twice the major axis so:
PF1 + PF2 = 2a
Where P is the point, F1 and F2 the foci and a the semi major axis.
If the sum is less then 2a the point will be inside the ellispe.
Wikipedia

Collision test between a triangle and a rectangle (AABB) in 2D

I've spent a good amount of time getting intersections working correctly between various 2D shapes (circle-circle, circle-tri, circle-rect, rect-rect - a huge thanks to those who've solved such problems from which I drew my solutions from) for a simple project and am now in the process of trying to implement an triangle-AABB intersection test.
I'm a bit stuck however. I've tried searching online and thinking it through however I've been unable to get any ideas. The thing that's given me the biggest issue at the moment is checking whether the edges of triangle (which is an isosceles btw) intersect the rectangle when no vertexes lie within the rectangle.
Any ideas how I could get this working?
EDIT: To give a bit more insight as to stages as I think they should occur:
1 - Check to see if any vertexes lie with in the rectangle (this part is easy). If yes, collision, otherwise continue.
2 - Check to see if any edges are intersecting the rectangle. This is where I'm stuck. I have little idea how to implement this.
I'd calculate a collection of equations which define the 4 lines of the rectangle, and then solve against a collection of equations which define lines of the triangle.
For example, gievn a rectangle with lowest point (x1, y1) and one side having a gradient of g, one of the lines of the rectangle will be y = gx + y1. Find equations to represent the other 3 sides of the rectangle as well.
The lines which form the sides of the triangle will be calculated similarly. The equation for a line given two points is
y - y1 = (x - x1) * (y2 - y1)/(x2 - x1)
If there are any possible x & y values that satisy all 7 equations then you have an intersection.
edit: I realise that although this is a simple algorithm it might be tricky to code; another option is to calculate formulae for the intervals that form each edge (essentially lines with a min and max value) and solve these.

Algorithm for Polygon Image Fill

I want an efficient algorithm to fill polygon with an Image, I want to fill an Image into Trapezoid. currently I am doing it in two steps
1) First Perform StretchBlt on Image,
2) Perform Column by Column vertical StretchBlt,
Is there any better method to implement this? Is there any Generic and Fast algorithm which can fill any polygon?
Thanks,
Sunny
I can't help you with the distortion part, but filling polygons is pretty simple, especially if they are convex.
For each Y scan line have a table indexed by Y, containing a minX and maxX.
For each edge, run a DDA line-drawing algorithm, and use it to fill in the table entries.
For each Y line, now you have a minX and maxX, so you can just fill that segment of the scan line.
The hard part is a mental trick - do not think of coordinates as specifying pixels. Think of coordinates as lying between the pixels. In other words, if you have a rectangle going from point 0,0 to point 2,2, it should light up 4 pixels, not 9. Most problems with polygon-filling revolve around this issue.
ADDED: OK, it sounds like what you're really asking is how to stretch the image to a non-rectangular shape (but trapezoidal). I would do it in terms of parameters s and t, going from 0 to 1. In other words, a location in the original rectangle is (x + w0*s, y + h0*t). Then define a function such that s and t also map to positions in the trapezoid, such as ((x+t*a) + w0*s*(t-1) + w1*s*t, y + h1*t). This defines a coordinate mapping between the two shapes. Then just scan x and y, converting to s and t, and mapping points from one to the other. You probably want to have a little smoothing filter rather than a direct copy.
ADDED to try to give a better explanation:
I'm supposing both your rectangle and trapezoid have top and bottom edges parallel with the X axis. The lower-left corner of the rectangle is <x0,y0>, and the lower-left corner of the trapezoid is <x1,y1>. I assume the rectangle's width and height are <w,h>.
For the trapezoid, I assume it has height h1, and that it's lower width is w0, while it's upper width is w1. I assume it's left edge "slants" by a distance a, so that the position of its upper-left corner is <x1+a, y1+h1>. Now suppose you iterate <x,y> over the rectangle. At each point, compute s = (x-x0)/w, and t = (y-y0)/h, which are both in the range 0 to 1. (I'll let you figure out how to do that without using floating point.) Then convert that to a coordinate in the trapezoid, as xt = ((x1 + t*a) + s*(w0*(1-t) + w1*t)), and yt = y1 + h1*t. Then <xt,yt> is the point in the trapezoid corresponding to <x,y> in the rectangle. Now I'll let you figure out how to do the copying :-) Good luck.
P.S. And please don't forget - coordinates fall between pixels, not on them.
Would it be feasible to sidestep the problem and use OpenGL to do this for you? OpenGL can render to memory contexts and if you can take advantage of any hardware acceleration by doing this that'll completely dwarf any code tweaks you can make on the CPU (although on some older cards memory context rendering may not be able to take advantage of the hardware).
If you want to do this completely in software MESA may be an option.

how to determine polygon rotation angle

I am writing a program (.net) to create a stadium style layout and need to determine the angle of rotation for each polygon compared to the horizontal.
This is so i can construct the contents of the polygon and also rotate this correctly to fit inside.
Given the below image as an example to simulate each variant of the facing direction (indicated by the red line) how could i determine the the rotation angle needed to get the shape to have the red line on top as is already shown by shape 5.
http://i40.tinypic.com/16ifhoo.gif
I have found logic to determine the angle of the points that make up the red line, but I also need to know the rotation to get it back to horizontal.
I'm not sure if i need some central reference point for all polygons to help.
How could I best solve this?
If you know the angle of the red line for some polygon (a, say), then the polygon is on one side or other of that line. So:
Use the average colour of some pixels near the line on both sides to determine which is the case.
If the polygon is above the line, the rotation angle is 180+a.
If the polygon is below the line, the rotation is a.
where above and below correspond to the smaller-angle side and larger-angle sides of the line according to how you measure a.
I would try to calculate the normal vectors on each red line (eg. 0 degrees for polygon 5, 45 degrees for 4, 90 degrees for 3, etc.) and then the angle you need to rotate that normal - and thus the matching polygon - so that the normal "points up" should be very simple.
Unfortunately I don't have the needed formulae available for you off the top of my head, but Googling "normal vector" and/or searching for it on Wikipedia should get you started just fine, I think. Possibly in the direction of the so called 'cross product'.
No central reference point for all polygons should be needed for this (normal direction is not related to absolute coordinates).
sin, cos, tan functions allow you to convert from triangle edge ratio to degrees.
Imagine, one end of red line is at (x1,y1) and other end is at (x2,y2). You can treat red line as hipotenuse of rectangular triangle and use arctan to get degrees.
Ratio between catheti is (x2-x1) / (y2 - y1). Rotation of red line then is arctan((x2-x1) / (y2 - y1)). Watch out for situations when y1-y1 is 0!
Let's try one example from your picture, polygon 6 with coords (55, 65) and (65, 55). Type in google: "arctan((65-55)/(55-65)) in degrees"

Resources