Copying PVectors in Processing - processing

PVector a = new PVector(1, 2);
PVector b = a;
PVector c = a.copy();
PVector d = a.get();
Not using .copy() method change one of my drawing.Is there any differences between b, c, d PVectors???

get() and copy() are functionally identical -- each returns a deep copy of the PVector.
PVector b = a; creates a reference b that points to the same PVector object that a points to.
Therefore, there are differences between the b, and c & d PVectors.
Let's use your code and change the value of a after instantiating the other variables to see how they differ:
PVector a = new PVector(1, 2);
PVector b = a;
PVector c = a.copy();
PVector d = a.get();
a.x = 4;
println(a.x);
println(b.x);
println(c.x);
println(d.x);
Output:
4.0
4.0
1.0
1.0

Related

How to generate a helico-spiral by visualizing formula or equation

I tried to visualize the formula of helico-spiral by programming but I failed to get the results I wanted. I don't know if I made an error when converting polar coordinates to Cartesian coordinates.
Here is my code:
float alpha;
float beta;
float A;
for (int i = 0; i < num; i++) {
float theta = i * 0.1 * $PI;
float r = A * exp(1.0 / tan(alpha) * theta);
float x = r * sin(beta) * cos(theta);
float y = r * sin(beta) * sin(theta);
float z = -1.0 * A * cos(beta);
vector pos = set(x, z, 0); // point position
}
I customized alpha, beta and theta and wanted to find the point coordinates on the helix through the radius r.
Start with parametrized spiral:
H = max height
R = max radius
n = number of screws
t = <0,1> input parameter
a = 2.0*M_PI*n*t;
r = R*t;
h = H*(1.0-t);
x = r*cos(a);
y = r*sin(a);
z = h;
Now just as you want to parametrize the spiral by r just compute t form r:
t = r/R;
so:
t = r/R;
h = H*(1.0-t);
a = 2.0*M_PI*n*t;
x = r*cos(a);
y = r*sin(a);
z = h;
so simply do a for loop where r goes from 0 to R with some small step and render lines between the computed points ...
Also the dependence between H,R is:
tan(Beta) = R/H
---------------
R = H*tan(Beta)
H = R/tan(Beta)
Beta = atan(R/H)

OpenGL intersection between vector and face

I have a terrain and an object which should moves over the terrain so I made a function that can detect which face is the origin of the object locate above so I should set the Y of the object with the accurate height of the intersection point between the vector from the object origin perpendicular with the face, I have the three vertices of the face so I can calculate its normal and its origin and maximum and minimum pointes (bounded box).
enter image description here
Edit:
the question in another form:
if I know x and z of a point over a triangle in the 3D space how can I know it y if it is a point in the triangle?
the Möller–Trumbore intersection algorithm
this is the implementation:
bool EngineItem::checkIntersection(glm::vec3& rayOrigin, glm::vec3& rayVector, Face& face, glm::vec3& point) {
const float EPSILON = 0.0000001;
glm::vec3 vertex0 = face.v1;
glm::vec3 vertex1 = face.v2;
glm::vec3 vertex2 = face.v3;
glm::vec3 edge1, edge2, h, s, q;
float a, f, u, v;
edge1 = vertex1 - vertex0;
edge2 = vertex2 - vertex0;
h = glm::cross(rayVector, edge2);
a = glm::dot(edge1, h);
if (a > -EPSILON && a < EPSILON)
return false;
f = 1 / a;
s = rayOrigin - vertex0;
u = f * glm::dot(s, h);
if (u < 0.0 || u > 1.0)
return false;
q = glm::cross(s, edge1);
v = f * glm::dot(rayVector, q);
if (v < 0.0 || u + v > 1.0)
return false;
float t = f * glm::dot(edge2, q);
if (t > EPSILON) {
glm::vec3 plus = glm::normalize(rayVector) * (t * glm::length(rayVector));
point = rayOrigin + plus;
return true;
} else
return false;
}

find shifted coordinate in skewed square

I have square, I know the X,Y coordinate for the (A,B,C,D) each, coordinate for (E,F,G,H) and the position for the circle inside first box (I,J).
so ..
I want to find the coordinates for the same circle inside the second box .. base on all the data have.
You need to find the transform from the first box to the second
B=T*A
so you need to find T which is a 3x3 matrix if this is on the plane
solve the equations as shown on this page http://andrew.gibiansky.com/blog/image-processing/image-morphing/
and he has the program too - you only need three points from the first quadrangle and the corresponding three points in the second quadrangle
private static float[] calculateTransform(Polygon pOriginal, Polygon pFinal){
float a = pFinal.xpoints[0];
float b = pFinal.ypoints[0];
float c = pFinal.xpoints[1];
float d = pFinal.ypoints[1];
float e = pFinal.xpoints[2];
float f = pFinal.ypoints[2];
float A = pOriginal.xpoints[0];
float B = pOriginal.ypoints[0];
float C = pOriginal.xpoints[1];
float D = pOriginal.ypoints[1];
float E = pOriginal.xpoints[2];
float F = pOriginal.ypoints[2];
float x = ((B-D)*(e-c) - (a-c)*(F-D)) / ((B-D)*(E-C) - (A-C)*(F-D));
float y = (a*(E-C) + A*(c-e) - c*E + e*C)/(A*(D-F) + B*(E-C) + C*F - D*E);
float t = c - x*C - y*D;
float z = ((B-D)*(f-d) - (b-d)*(F-D)) / ((B-D)*(E-C) - (A-C)*(F-D));
float w = (b*(E-C) + A*(d-f) - d*E + f*C)/(A*(D-F) + B*(E-C) + C*F - D*E);
float s = d - z*C - w*D;
float[] transform = {x, y, z, w, t, s};
return transform;
}
then apply T to any point on A to get the corresponding point on B
private static float[] applyTransform(float x, float y, float[] transform){
float a = transform[0];
float b = transform[1];
float c = transform[2];
float d = transform[3];
float t = transform[4];
float s = transform[5];
float p = a * x + b * y + t;
float q = c * x + d * y + s;
float[] result = {p, q};
return result;
}

Reflect vector in 3D space

A vector should be reflected when intersecting a mesh. When applying the following formula to reflect a vector, the result is set off. I am using toxiclibs in Processing.
// Get the normal of the face that is intersected.
ReadonlyVec3D n = isect.normal;
// calculate the reflected vector b
// a is the green point in the screenshot
b = a.sub(n.scale(2 * a.dot(n)));
b = b.add(b.getNormalized());
EDIT: When taking into account to create a directional vector by subtracting the last point before the intersection with the intersection, still the reflection is off.
Vec3D id = b.sub(isect.pos);
id.normalize();
b = n.scale(2 * id.dot(n)).sub(id);
I had the question a while back and found a few helpful resources:
Paul Bourke's solution for Line-Plane intersection
Vector reflection on 3D Kingdoms
Here's the snippet I used then:
import toxi.geom.Vec3D;
Vec3D[] face = new Vec3D[3];
float ai = TWO_PI/3;//angle increment
float r = 300;//overall radius
float ro = 150;//random offset
Vec3D n;//normal
Ray r1;
void setup() {
size(500, 500, P3D);
for (int i = 0 ; i < 3; i++) face[i] = new Vec3D(cos(ai * i) * r + random(ro), random(-50, 50), sin(ai * i) * r + random(ro));
r1 = new Ray(new Vec3D(-100, -200, -300), new Vec3D(100, 200, 300));
}
void draw() {
background(255);
lights();
translate(width/2, height/2, -500);
rotateX(map(mouseY, 0, height, -PI, PI));
rotateY(map(mouseX, 0, width, -PI, PI));
//draw plane
beginShape(TRIANGLES);
for (Vec3D p : face) vertex(p.x, p.y, p.z);
endShape();
//normals
Vec3D c = new Vec3D();//centroid
for (Vec3D p : face) c.addSelf(p);
c.scaleSelf(1.0/3.0);
Vec3D cb = face[2].sub(face[1]);
Vec3D ab = face[0].sub(face[1]);
n = cb.cross(ab);//compute normal
n.normalize();
line(c.x, c.y, c.z, n.x, n.y, n.z);//draw normal
pushStyle();
//http://paulbourke.net/geometry/planeline/
//line to plane intersection u = N dot ( P3 - P1 ) / N dot (P2 - P1), P = P1 + u (P2-P1), where P1,P2 are on the line and P3 is a point on the plane
Vec3D P2SubP1 = r1.end.sub(r1.start);
Vec3D P3SubP1 = face[0].sub(r1.start);
float u = n.dot(P3SubP1) / n.dot(P2SubP1);
Vec3D P = r1.start.add(P2SubP1.scaleSelf(u));
strokeWeight(5);
point(P.x, P.y, P.z);//point of ray-plane intersection
//vector reflecting http://www.3dkingdoms.com/weekly/weekly.php?a=2
//R = 2*(V dot N)*N - V
//Vnew = -2*(V dot N)*N + V
//PVector V = PVector.sub(r1.start,r1.end);
Vec3D V = r1.start.sub(P);
Vec3D R = n.scaleSelf(2 * (V.dot(n))).sub(V);
strokeWeight(1);
stroke(0, 192, 0);
line(P.x, P.y, P.z, R.x, R.y, R.z);
stroke(192, 0, 0);
line(r1.start.x, r1.start.y, r1.start.z, P.x, P.y, P.z);
stroke(0, 0, 192);
line(P.x, P.y, P.z, r1.end.x, r1.end.y, r1.end.z);
popStyle();
}
void keyPressed() {
setup();
}//reset
class Ray {
Vec3D start = new Vec3D(), end = new Vec3D();
Ray(Vec3D s, Vec3D e) {
start = s ;
end = e;
}
}
Note that this is a basic proof of concept.
Toxiclibs may already provide Ray/Face classes.
Assuming you have the incident direction id and the normal at the point of intersection n, then the reflection rd is
rd = 2 * dot(n,id) * n - id
where all the vectors are normalized.
In your case, if b is the green point, and isect is the point of intersection then id = b - isect normalized.
So the reflection ray r (assuming it has an origin and a direction) is
r.direction = rd
r.origin = isect
You can also look at this Wikipedia article. https://en.wikipedia.org/wiki/Specular_reflection.

How to calculate the coordinates of a arrowhead based on the arrow?

I have a line that is based on two (x,y) coordinates I know. This line has a starting and an end point. Now I want to add an arrowhead at the end point of the line.
I know that the arrow is an equilateral triangle, and therefore each angle has 60 degrees. Additionally, I know the length of one side, which will be 20. I also no one edge of the triangle (that is the end point of the line).
How can I calculate the other two points of the triangle? I know I should use some trigonometry but how?
P.s. The endpoint of the line should be the arrowhead's tip.
You don't need trig., just some vector arithmetic...
Say the line goes from A to B, with the front vertex of the arrowhead at B. The length of the arrowhead is h = 10(√3) and its half-width is w = 10. We'll denote the unit vector from A to B as U = (B - A)/|B - A| (i.e., the difference divided by the length of the difference), and the unit vector perpendicular to this as V = [-Uy, Ux].
From these quantities, you can calculate the two rear vertices of the arrowhead as B - hU ± wV.
In C++:
struct vec { float x, y; /* … */ };
void arrowhead(vec A, vec B, vec& v1, vec& v2) {
float h = 10*sqrtf(3), w = 10;
vec U = (B - A)/(B - A).length();
vec V = vec(-U.y, U.x);
v1 = B - h*U + w*V;
v2 = B - h*U - w*V;
}
If you want to specify different angles, then you will need some trig. to calculate different values of h and w. Assuming you want an arrowhead of length h and tip-angle θ, then w = h tan(θ/2). In practice, however, it's simplest to specify h and w directly.
Here's a sample LINQPad program that shows how to do that:
void Main()
{
const int imageWidth = 512;
Bitmap b = new Bitmap(imageWidth , imageWidth , PixelFormat.Format24bppRgb);
Random r = new Random();
for (int index = 0; index < 10; index++)
{
Point fromPoint = new Point(0, 0);
Point toPoint = new Point(0, 0);
// Ensure we actually have a line
while (fromPoint == toPoint)
{
fromPoint = new Point(r.Next(imageWidth ), r.Next(imageWidth ));
toPoint = new Point(r.Next(imageWidth ), r.Next(imageWidth ));
}
// dx,dy = arrow line vector
var dx = toPoint.X - fromPoint.X;
var dy = toPoint.Y - fromPoint.Y;
// normalize
var length = Math.Sqrt(dx * dx + dy * dy);
var unitDx = dx / length;
var unitDy = dy / length;
// increase this to get a larger arrow head
const int arrowHeadBoxSize = 10;
var arrowPoint1 = new Point(
Convert.ToInt32(toPoint.X - unitDx * arrowHeadBoxSize - unitDy * arrowHeadBoxSize),
Convert.ToInt32(toPoint.Y - unitDy * arrowHeadBoxSize + unitDx * arrowHeadBoxSize));
var arrowPoint2 = new Point(
Convert.ToInt32(toPoint.X - unitDx * arrowHeadBoxSize + unitDy * arrowHeadBoxSize),
Convert.ToInt32(toPoint.Y - unitDy * arrowHeadBoxSize - unitDx * arrowHeadBoxSize));
using (Graphics g = Graphics.FromImage(b))
{
if (index == 0)
g.Clear(Color.White);
g.DrawLine(Pens.Black, fromPoint, toPoint);
g.DrawLine(Pens.Black, toPoint, arrowPoint1);
g.DrawLine(Pens.Black, toPoint, arrowPoint2);
}
}
using (var stream = new MemoryStream())
{
b.Save(stream, ImageFormat.Png);
Util.Image(stream.ToArray()).Dump();
}
}
Basically, you:
Calculate the vector of the arrow line
Normalize the vector, ie. making its length 1
Calculate the ends of the arrow heads by going:
First back from the head a certain distance
Then perpendicular out from the line a certain distance
Note that if you want the arrow head lines to have a different angle than 45 degrees, you'll have to use a different method.
The program above will draw 10 random arrows each time, here's an example:
Let's your line is (x0,y0)-(x1,y1)
Backward direction vector (dx, dy) = (x0-x1, y0-y1)
It's norm Norm = Sqrt(dx*dx+dy*dy)
Normalize it: (udx, udy) = (dx/Norm, dy/Norm)
Rotate by angles Pi/6 and -Pi/6
ax = udx * Sqrt(3)/2 - udy * 1/2
ay = udx * 1/2 + udy * Sqrt(3)/2
bx = udx * Sqrt(3)/2 + udy * 1/2
by = - udx * 1/2 + udy * Sqrt(3)/2
Your points: (x1 + 20 * ax, y1 + 20 * ay) and (x1 + 20 * bx, y1 + 20 * by)
I want to contribute my answer in C# based on Marcelo Cantos' answer since the algorithm works really well. I wrote a program to calculate the centroid of a laser beam projected on the CCD array. After the centroid is found, the direction angle line is drawn and I need the arrow head pointing at that direction. Since the angle is calculated, the arrow head would have to follow the angle in any of the direction.
This code gives you the flexibility of changing the arrow head size as shown in the pictures.
First you need the vector struct with all the necessary operators overloading.
private struct vec
{
public float x;
public float y;
public vec(float x, float y)
{
this.x = x;
this.y = y;
}
public static vec operator -(vec v1, vec v2)
{
return new vec(v1.x - v2.x, v1.y - v2.y);
}
public static vec operator +(vec v1, vec v2)
{
return new vec(v1.x + v2.x, v1.y + v2.y);
}
public static vec operator /(vec v1, float number)
{
return new vec(v1.x / number, v1.y / number);
}
public static vec operator *(vec v1, float number)
{
return new vec(v1.x * number, v1.y * number);
}
public static vec operator *(float number, vec v1)
{
return new vec(v1.x * number, v1.y * number);
}
public float length()
{
double distance;
distance = (this.x * this.x) + (this.y * this.y);
return (float)Math.Sqrt(distance);
}
}
Then you can use the same code given by Marcelo Cantos, but I made the length and half_width of the arrow head variables so that you can define that when calling the function.
private void arrowhead(float length, float half_width,
vec A, vec B, ref vec v1, ref vec v2)
{
float h = length * (float)Math.Sqrt(3);
float w = half_width;
vec U = (B - A) / (B - A).length();
vec V = new vec(-U.y, U.x);
v1 = B - h * U + w * V;
v2 = B - h * U - w * V;
}
Now you can call the function like this:
vec leftArrowHead = new vec();
vec rightArrowHead = new vec();
arrowhead(20, 10, new vec(circle_center_x, circle_center_y),
new vec(x_centroid_pixel, y_centroid_pixel),
ref leftArrowHead, ref rightArrowHead);
In my code, the circle center is the first vector location (arrow butt), and the centroid_pixel is the second vector location (arrow head).
I draw the arrow head by storing the vector values in the points for graphics.DrawPolygon() function in the System.Drawings. Code is shown below:
Point[] ppts = new Point[3];
ppts[0] = new Point((int)leftArrowHead.x, (int)leftArrowHead.y);
ppts[1] = new Point(x_cm_pixel,y_cm_pixel);
ppts[2] = new Point((int)rightArrowHead.x, (int)rightArrowHead.y);
g2.DrawPolygon(p, ppts);
You can find angle of line.
Vector ox = Vector(1,0);
Vector line_direction = Vector(line_begin.x - line_end.x, line_begin.y - line_end.y);
line_direction.normalize();
float angle = acos(ox.x * line_direction.x + line_direction.y * ox.y);
Then use this function to all 3 points using found angle.
Point rotate(Point point, float angle)
{
Point rotated_point;
rotated_point.x = point.x * cos(angle) - point.y * sin(angle);
rotated_point.y = point.x * sin(angle) + point.y * cos(angle);
return rotated_point;
}
Assuming that upper point of arrow's head is line's end it will perfectly rotated and fit to line.
Didn't test it =(
For anyone that is interested, #TomP was wondering about a js version, so here is a javascript version that I made. It is based off of #Patratacus and #Marcelo Cantos answers. Javascript doesn't support operator overloading, so it isn't as clean looking as C++ or other languages. Feel free to offer improvements.
I am using Class.js to create classes.
Vector = Class.extend({
NAME: "Vector",
init: function(x, y)
{
this.x = x;
this.y = y;
},
subtract: function(v1)
{
return new Vector(this.x - v1.x, this.y - v1.y);
},
add: function(v1)
{
return new Vector(this.x + v1.x, this.y + v1.y);
},
divide: function(number)
{
return new Vector(this.x / number, this.y / number);
},
multiply: function(number)
{
return new Vector(this.x * number, this.y * number);
},
length: function()
{
var distance;
distance = (this.x * this.x) + (this.y * this.y);
return Math.sqrt(distance);
}
});
And then a function to do the logic:
var getArrowhead = function(A, B)
{
var h = 10 * Math.sqrt(3);
var w = 5;
var v1 = B.subtract(A);
var length = v1.length();
var U = v1.divide(length);
var V = new Vector(-U.y, U.x);
var r1 = B.subtract(U.multiply(h)).add(V.multiply(w));
var r2 = B.subtract(U.multiply(h)).subtract(V.multiply(w));
return [r1,r2];
}
And call the function like this:
var A = new Vector(start.x,start.y);
var B = new Vector(end.x,end.y);
var vec = getArrowhead(A,B);
console.log(vec[0]);
console.log(vec[1]);
I know the OP didn't ask for any specific language, but I came across this looking for a JS implementation, so I thought I would post the result.

Resources