I have a 2 vectors of size 4 to store coordinates of a shape (square/rectangle). 1st vector is for x and 2nd for y. To find out the area of the shape, I need the difference in their length. How do I find the difference between 2 elements within the same vector? Using square as an example:
vector<int> x(4);
vector<int> y(4);
double Square::computeArea()
{
int length;
double area;
if (x[0] == x[1]) //x coordinates are the same
{
length = y[0] - y[1]; //difference in y coordinates to find the length, need help here
}
else if (x[1] == x[2]
{
length = y[1] - y[2];
}
else if ... //repeat
area = length * length;
if (area < 0) { area = -area; }
setArea(area)
return area;
}
If your rectangle has edges which are parallel to the axis, and the points are ordered clockwise (or counterclockwise), you can simply use the first and third element of the arrays:
int yedge, xedge;
xedge = abs(x[0] - x[2]);
if ( xedge == 0 ) //beware, this check works well only for ints!
return area = 0.0;
else yedge = abs(y[0] - y[2]);
return area = xedge * yedge;
If you have more general convex quadrilaterals use something like this:
int dx20 = x[2] - x[0];
int dy10 = y[1] - y[0];
int dy20 = y[2] - y[0];
int dx10 = x[1] - x[0];
int dy30 = y[3] - y[0];
int dx30 = x[3] - x[0];
area = 0.5*abs(dx20*dy10-dy20*dx10);
area += 0.5*abs(dx20*dy30-dy20*dx30);
The beauty of C++ and OOP is that you can think more in terms of the problem than how to program it.
If I were in your place I would use std::pair to save the coordinates.
And have a class representing the rectangle.
I am using the distance between point 1 and 2 as length, and point 1 and 4 as width. It may not be the correct approach in all cases but it should show you have to go about programming your function.
using namespace std;
class Rectangle // Class Rectangle
{
public:
Rectangle(vector<pair<double, double>> neWcoordinates);
double computeArea();
private:
vector<pair<double, double>> coordinates;
};
double Rectangle::computeArea()
{
double length = sqrt(pow(coordinates[0].first-coordinates[1].first,2)+pow(coordinates[0].second-coordinates[1].second,2)
);
double width = sqrt(pow(coordinates[0].first-coordinates[3].first,2)+pow(coordinates[0].second-coordinates[3].second,2));
return length*width;
}
Related
Looking for a C++ solution.
I had thoughts whether to ask this question over here or MathExchange etc. but since it's more of a programming based question thus posting here.
Real problem:
I have an XML with field as:
<part name='01' x='351' y='151'/>
Where x and y, I am storing as QPointf object. Also, I require the name=01 value which I am mapping together with the QPointf object to create a map.
Now there are certain operations that I need to do on this map :
First I need to get all the points(QPointf) and draw over an image.
Second, I will modify the x and y value of certain points getting the points from the GUI.
When I get the points from GUI, I need to check x and y value in each Qpointf inside map.
Problem in simpler form:
I am looking for a data structure such that instead of having a map of key and QPointf, it makes parsing and looking for x and y value of points(QPointf) easier. Just that the QPointf and key should form a unique pair with each other, so that parsing through the entire list of points to find certain (x,y) and modifying it is faster and even when x and y value of QPointf is modified the key attached to it is same.
PS: I hope I was clear with the problem, if there is anything unclear then please edit/comment so that the question can be improved.
My guess is here that your most important aspect is finding a certain set of x and y points when a user uses the UI. There are many acceleration structures possible, but I would probably recommend a point index grid. That is, you partition the indices of points into 2D buckets. When a user chooses a point in the UI, you can do a quick look-up on what bucket the point is in, and you can then iterate over only the points present in that bucket to find the actual point.
As for your data, I would store it in an array:
struct NamePoint {
int name, x, y;
};
std::vector<NamePoint> points;
Now you would create a point index grid that refers to the points array. Implementing one yourself might be worthwhile, but otherwise I know that there exists an OpenVDB version that works.
I made a small dirty implementation so you can see the principle. I have no checks for inputs, so if you're not careful you will access out of the bounds of the vector (e.g., calling pointIndexGrid.indicesForPoint(5, 5) gives segmentation fault).
#include <iostream>
#include <vector>
#include <limits>
struct NamePoint {
int name, x, y;
};
template <typename T> // Just so any array type can work
struct PointIndexGrid {
using ArrayType = T;
using size_type = typename ArrayType::size_type;
PointIndexGrid(const ArrayType& points, int gridSize)
: mGridSize(gridSize)
{
// Find the domain. We will create a 2D vector which will all contain another vector with indices.
maxX = maxY = std::numeric_limits<int>::min();
minX = minY = std::numeric_limits<int>::max();
for (const auto& p : points) {
maxX = p.x > maxX ? p.x : maxX;
maxY = p.y > maxY ? p.y : maxY;
minX = p.x < minX ? p.x : minX;
minY = p.x < minY ? p.x : minY;
}
// create buckets
int nbrXBuckets = (maxX - minX)/mGridSize + 1; // Due to integer arithmetics we round down -- lets add one extra just in case
int nbrYBuckets = (maxY - minY)/mGridSize + 1;
for (int n = 0; n < nbrXBuckets; ++n) {
mBuckets.emplace_back(std::vector<std::vector<size_type>>(nbrYBuckets));
}
// Partition points
for (size_type i = 0; i < points.size(); ++i) {
int xBucket = (points[i].x - minX)/mGridSize; // this is the method how to easily calculate the bucket. Pure arithmetics -- goes fast
int yBucket = (points[i].y - minY)/mGridSize;
mBuckets[xBucket][yBucket].emplace_back(i);
}
}
std::vector<size_type> indicesForPoint(int x, int y)
{
int xBucket = (x - minX)/mGridSize; // Same as above
int yBucket = (y - minY)/mGridSize;
return mBuckets[xBucket][yBucket];
}
private:
int mGridSize;
int maxX, minX;
int maxY, minY;
std::vector<std::vector<std::vector<size_type>>> mBuckets;
};
int main() {
std::vector<NamePoint> points;
points.emplace_back(NamePoint{1, 1, 1});
points.emplace_back(NamePoint{2, 1, 2});
points.emplace_back(NamePoint{3, 1, 2});
points.emplace_back(NamePoint{4, 2, 2});
points.emplace_back(NamePoint{5, 3, 3});
PointIndexGrid<std::vector<NamePoint>> pointIndexGrid(points, 2);
std::cout << "Indices for (1, 1): " << std::endl;
for (const auto& i : pointIndexGrid.indicesForPoint(1, 1)) {
std::cout << " " << i << std::endl;
}
std::cout << "Indices for (3, 3): " << std::endl;
for (const auto& i : pointIndexGrid.indicesForPoint(3, 3)) {
std::cout << " " << i << std::endl;
}
}
This prints out:
Indices for (1, 1):
0
1
2
3
Indices for (3, 3):
4
So to find a point at a specific (x, y):
Partition all points using the PointIndexGrid.
Use pointIndexGrid.indicesForPoint(x, y).
Iterate through all indices there (and look up the points in the points-array).
Grab the point that you want.
So if I understood correctly you just want an easy way to store your points data.
This isn't the best in terms of performance but if you are not planing on changing it every frame it will work no problem:
#include <map>
typedef std::map<int, std::pair<float, float>> PointContainer;
QPointf* fromPointContainer(PointContainer points)
{
QPointf array = new QPointf[points.size()];
for (size_t i; i < points.size(); i++)
array[i] = QPointf(points[i].first, points[i].second);
return array;
}
int main() {
PointContainer points;
points[0] = { 1.6f/*x*/, 5.8f/*y*/ };
QPointf* array = fromPointContainer(points);
//render here
delete array;//don't forget to delete the array allocated with new
return 0;
}
How do I find the area of square or rectangle assuming user has entered some accurate points to form a square or rectangle.
I need to calculate the area inside the square class and rectangle class respectively.
I have 2 vector of coordinates, coordX and coordY.
My idea is when either or x or y has same value it will be a line and I can find the distance x2 but I'm not sure how to implement it in code.
double Square::computeArea() {
double area;
for (int x = 0; x < coordX.size; x++) {
for (int y = 0; y < coordY.size; y++) {
if (coordX[x] == coordY[y])
{
//....
}
}
}
return area;
}
This is how i populate my vector with user input
Square Square;
for ( int i = 1; i <= 4; i++) {
cout << "Please enter x-coordinate of pt " << i << ": ";
cin >> x;
Square.setXCoordinate(x);
cout << "Please enter y-coordinate of pt " << i << ": ";
cin >> y;
Square.setYCoordinate(y);
}
this is my mutator function in my class. Square inherit from ShapeTwoD
void ShapeTwoD::setXCoordinate(int x) {
coordX.push_back(x);
}
void ShapeTwoD::setYCoordinate(int y) {
coordY.push_back(y);
}
No need for square root.
Take two edges from one vertex, rotate one by 90°, take dot product.
double dx1 = coordX[3] - coordX[0];
double dy1 = coordY[3] - coordY[0];
double dx2 = coordX[1] - coordX[0];
double dy2 = coordY[1] - coordY[0];
double area = abs(dx1*dy2 - dy1*dx2)
As a bonus, this will calculate the correct area for all parallelograms, not just rectangles.
This assumes, the points are entered in clockwise or couter-clockwise order. If that's not the case, find out which point has the greatest distance to point[0] then discard it and use the other two instead of 1 and 3 above.
Assuming your coordinates are something like
// 3-----------2
// | |
// | |
// 0-----------1
Then you could do
#include <cmath>
double distance(double x1, double x2, double y1, double y2)
{
return std::sqrt(std::pow(x2 - x1, 2) + std::pow(y2 - y1, 2));
}
double Square::computeArea() const
{
double length = distance(coordX[0], coordX[1], coordY[0], coordY[1]);
double width = distance(coordX[0], coordX[3], coordY[0], coordY[3]);
return length * width;
}
This allows your rectangle to be at any arbitrary orientation, instead of x-y axis aligned. You just need to maintain a convention of the indexes of the corners, like in my example diagram.
Lets say I have two AABB based areas, each area defined by two coordinates mins{x, y} and maxs{x, y}, I want to find the middle connection point between them.
Since my english is not good, I can't explain all with my words,
see the following picture for easier understanding:
http://i.*.com/WokivEe.png
All I need to find is the red point coordinates.
so If we move this into programming question, actual data structures would look like this:
struct Vec2D {
float x, y;
}
struct Rectangle {
Vec2D min;
Vec2D max;
}
Rectangle obj[2]
Anyone got an idea for an algorithm?
Along either the X or Y axis, sort the coordinates of the sides that touch into order. Then average the 2nd and 3rd ones in that list to find their midpoint. I hope this answers the question sufficiently.
Here is a little algorithm that first find which sides of the objects are closest, and then uses the 4 points along the common side to make a list, sorted along the common axis. The average of the 2 middle points of the sorted list are the answer. This will work for both horizontal and vertical sides. I added accessor functions to the data structures so that they can be indexed; e.g., for a Vec2D, coordinate(0) is the x value and coordinate(1) is the y value.
#include <math.h>
#include <iostream>
#include <limits>
struct Vec2D {
float x, y;
float coordinate(int axis)
{
return (axis & 1) ? y : x;
}
};
struct Rectangle {
Vec2D min;
Vec2D max;
Vec2D corner(int j)
{
return (j & 1) ? max : min;
}
// Get the other corner along the given axis
Vec2D along(int j, int ax)
{
Vec2D p = corner(j);
if (0 == ax)
{
p.x = corner(1-j).x;
}
else
{
p.y = corner(1-j).y;
}
return p;
}
};
using namespace std;
inline Vec2D* vp(const void* p)
{
return (Vec2D*) p;
}
static int compare_x(const void*a, const void*b)
{
if (vp(a)->x < vp(b)->x)
{
return -1;
}
else
if (vp(a)->x > vp(b)->x)
{
return 1;
}
return 0;
}
static int compare_y(const void*a, const void*b)
{
if (vp(a)->y < vp(b)->y)
{
return -1;
}
else
if (vp(a)->y > vp(b)->y)
{
return 1;
}
return 0;
}
int main(void) {
int ax; // axis index
int c0, c1;
float gap = numeric_limits<float>::max();
struct Rectangle obj[2] = {0,2,10,10,10,5,15,20};
struct
{
int ax,c0,c1;
} closest;
// Find out which sides are the closest to each other
for(ax = 0; 2 > ax; ++ax) // Look at x axis and y axis
{
for(c0 = 0; 2 > c0; ++c0) // Look at both corners of obj[0]
{
for(c1 = 0; 2 > c1; ++c1) // Look at both corners of obj[1]
{
float dist = fabs(obj[0].corner(c0).coordinate(ax) - obj[1].corner(c1).coordinate(ax));
if (dist < gap)
{
gap = dist;
closest.ax = ax;
closest.c0 = c0;
closest.c1 = c1;
}
}
}
}
int other = 1 - closest.ax; // The other axis
cout << "The closest gap is along the " << (closest.ax ? 'y' : 'x') << " axis\n";
cout << "The common side is along the " << (other ? 'y' : 'x') << " direction\n";
// Make a list of the 4 points along the common side
Vec2D list[4];
list[0] = obj[0].corner(closest.c0);
list[1] = obj[0].along(closest.c0, other);
list[2] = obj[1].corner(closest.c1);
list[3] = obj[1].along(closest.c1, other);
// Sort them into order along the common axis
qsort(list, 4, sizeof(Vec2D), closest.ax ? compare_x : compare_y);
// Get the average of the 2 middle points along the common axis.
Vec2D answer = {
(list[1].x + list[2].x) / 2,
(list[1].y + list[2].y) / 2
};
cout << "(" << answer.x << "," << answer.y << ")\n";
}
I was searching for the closest pair code and i found this which has used qsort() library function. I basically didn't get the concept of how it's compare parameter works. Explanation related to this particular code will be more appreciated. Thanks.
#include <iostream>
#include <float.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
// A structure to represent a Point in 2D plane
struct Point
{
int x, y;
};
/* Following two functions are needed for library function qsort().
Refer: http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */
// Needed to sort array of points according to X coordinate
int compareX(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->x - p2->x);
}
// Needed to sort array of points according to Y coordinate
int compareY(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->y - p2->y);
}
// A utility function to find the distance between two points
float dist(Point p1, Point p2)
{
return sqrt( (p1.x - p2.x)*(p1.x - p2.x) +
(p1.y - p2.y)*(p1.y - p2.y)
);
}
// A Brute Force method to return the smallest distance between two points
// in P[] of size n
float bruteForce(Point P[], int n)
{
float min = FLT_MAX;
for (int i = 0; i < n; ++i)
for (int j = i+1; j < n; ++j)
if (dist(P[i], P[j]) < min)
min = dist(P[i], P[j]);
return min;
}
// A utility function to find minimum of two float values
float min(float x, float y)
{
return (x < y)? x : y;
}
// A utility function to find the distance beween the closest points of
// strip of given size. All points in strip[] are sorted accordint to
// y coordinate. They all have an upper bound on minimum distance as d.
// Note that this method seems to be a O(n^2) method, but it's a O(n)
// method as the inner loop runs at most 6 times
float stripClosest(Point strip[], int size, float d)
{
float min = d; // Initialize the minimum distance as d
// Pick all points one by one and try the next points till the difference
// between y coordinates is smaller than d.
// This is a proven fact that this loop runs at most 6 times
for (int i = 0; i < size; ++i)
for (int j = i+1; j < size && (strip[j].y - strip[i].y) < min; ++j)
if (dist(strip[i],strip[j]) < min)
min = dist(strip[i], strip[j]);
return min;
}
// A recursive function to find the smallest distance. The array Px contains
// all points sorted according to x coordinates and Py contains all points
// sorted according to y coordinates
float closestUtil(Point Px[], Point Py[], int n)
{
// If there are 2 or 3 points, then use brute force
if (n <= 3)
return bruteForce(Px, n);
// Find the middle point
int mid = n/2;
Point midPoint = Px[mid];
// Divide points in y sorted array around the vertical line.
// Assumption: All x coordinates are distinct.
Point Pyl[mid+1]; // y sorted points on left of vertical line
Point Pyr[n-mid-1]; // y sorted points on right of vertical line
int li = 0, ri = 0; // indexes of left and right subarrays
for (int i = 0; i < n; i++)
{
if (Py[i].x <= midPoint.x)
Pyl[li++] = Py[i];
else
Pyr[ri++] = Py[i];
}
// Consider the vertical line passing through the middle point
// calculate the smallest distance dl on left of middle point and
// dr on right side
float dl = closestUtil(Px, Pyl, mid);
float dr = closestUtil(Px + mid, Pyr, n-mid);
// Find the smaller of two distances
float d = min(dl, dr);
// Build an array strip[] that contains points close (closer than d)
// to the line passing through the middle point
Point strip[n];
int j = 0;
for (int i = 0; i < n; i++)
if (abs(Py[i].x - midPoint.x) < d)
strip[j] = Py[i], j++;
// Find the closest points in strip. Return the minimum of d and closest
// distance is strip[]
return min(d, stripClosest(strip, j, d) );
}
// The main functin that finds the smallest distance
// This method mainly uses closestUtil()
float closest(Point P[], int n)
{
Point Px[n];
Point Py[n];
for (int i = 0; i < n; i++)
{
Px[i] = P[i];
Py[i] = P[i];
}
qsort(Px, n, sizeof(Point), compareX);
qsort(Py, n, sizeof(Point), compareY);
// Use recursive function closestUtil() to find the smallest distance
return closestUtil(Px, Py, n);
}
// Driver program to test above functions
int main()
{
Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};
int n = sizeof(P) / sizeof(P[0]);
cout << "The smallest distance is " << closest(P, n);
return 0;
}
The last parameter of qsort is a pointer to a function with a specific signature: it must take two void* pointers, and return an int that indicates which of the two passed items is smaller or if the two items are the same. The specifics are here, but generally a positive result indicates that the second item is smaller, a negative indicates that the first item is smaller, and zero indicates the equaliity.
The implementation of compareX
int compareX(const void* a, const void* b)
{
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->x - p2->x);
}
follows the general pattern for comparison functions. First, it converts the void* pointer to the Point type, because it "knows" that it is used together with an array of Point structures. Then it subtracts the x coordinates of the two points:
p1->x - p2->x
Note that the result of the subtraction is going to be positive if the second point's x is smaller, negative when the second point's x is greater, and zero when the two xs are the same. This is precisely what qsort wants the cmp function to do, so the subtraction operation fulfills the contract of the comparison function.
If I have a simple 2-D matrix with normalized values on x-axis between 0 and 1 and y-axys between 0 and 1, and I have 3 points in this matrix e.g. P1 (x=0.2,y=0.9), P2 (x=0.5,y=0.1) and P3 (x=0.9,y=0.4).
How can I simply calculate a curve thru this points, meaning having a function which is giving me the y for any x.
I now that there are any number of possible curves thru 3 points. But hey, you know what I mean: I want a smooth curve thru it, usable for audio-sample-interpolation, usable for calculation a volume-fade-curve, usable for calculating a monster-walking-path in a game.
Now I have searched the net for this question about 3 days, and I cannot believe that there is no usable solution for this task. All the text dealing about Catmull-rom-Splines, bezier-curves and all that theroretical stuff has all at least one point which doesn't make it for me usable. For example Catmull-Rom-splines need to have a fix distance between the control-points (I would use this code and set the 4. point-y to the 3. point y) :
void CatmullRomSpline(float *x,float *y,float x1,float y1,float x2,float y2,float x3,float y3,float x4,float y4,float u)
{
//x,y are calculated for x1,y1,x2,y2,x3,y3 and x4,y4 if u is the normalized distance (0-1) in relation to the distance between x2 and x3 for my whiched point
float u3,u2,f1,f2,f3,f4;
u3=u*u*u;
u2=u*u;
f1=-0.5f * u3 + u2 -0.5f *u;
f2= 1.5f * u3 -2.5f * u2+1.0f;
f3=-1.5f * u3 +2.0f * u2+0.5f*u;
f4=0.5f*u3-0.5f*u2;
*x=x1*f1+x2*f2+x3*f3+x4*f4;
*y=y1*f1+y2*f2+y3*f3+y4*f4;
}
But I don't see that x1 to x4 have any affect on the calculation of y, so I think x1 to x4 must have the same distance?
...
Or bezier-code doesn't calcuate the curve thru the points. The points (at least the 2. point) seem only to have a force-effect on the line.
typedef struct Point2D
{
double x;
double y;
} Point2D;
class bezier
{
std::vector<Point2D> points;
bezier();
void PushPoint2D( Point2D point );
Point2D GetPoint( double time );
~bezier();
};
void bezier::PushPoint2D(Point2D point)
{
points.push_back(point);
}
Point2D bezier::GetPoint( double x )
{
int i;
Point2D p;
p.x=0;
p.y=0;
if( points.size() == 1 ) return points[0];
if( points.size() == 0 ) return p;
bezier b;
for (i=0;i<(int)points.size()-1;i++)
{
p.x = ( points[i+1].x - points[i].x ) * x + points[i].x;
p.y = ( points[i+1].y - points[i].y ) * x + points[i].y;
if (points.size()<=2) return p;
b.PushPoint2D(p);
}
return b.GetPoint(x);
}
double GetLogicalYAtX(double x)
{
bezier bz;
Point2D p;
p.x=0.2;
p.y=0.9;
bz.PushPoint2D(p);
p.x=0.5;
p.y=0.1;
bz.PushPoint2D(p);
p.x=0.9;
p.y=0.4;
bz.PushPoint2D(p);
p=bz.GetPoint(x);
return p.y;
}
This is better than nothing, but it is 1. very slow (recursive) and 2. as I said doesn't really calculate the line thru the 2. point.
Is there a mathematical brain outside which could help me?
Thank you TOCS (Scott) for providing your code, I will also try it if I have some time. But what I have tested now is the hint by INFACT (answer 3): This "Largrange polynomials" are very very close to what I am searching for:
I have renamed my class bezier to curve, because I have added some code for lagrangeinterpolation. I also have added 3 pictures of graphical presentation what the code is calculation.
In Picture 1 you can see the loose middle point of the old bezier-function.
In Picture 2 you can now see the going thru all-points-result of lagrange interpolation.
In Picture 3 you can see the only problem, or should I say "thing which I also need to be solved" (anyway its the best solution till now): If I move the middle point, the curve to going to fast, to quick to the upper or lower boundaries). I would like it to go more smoothely to the upper and lower. So that it looks more logarithm-function like. So that it doesn't exeed the y-boundaries between 0 and 1 too soon.
Now my code looks like this:
curve::curve(void)
{
}
void curve::PushPoint2D(Point2D point)
{
points.push_back(point);
}
Point2D curve::GetPoint( double x )
{
//GetPoint y for x with bezier-mathematics...
//was the only calculating function in old class "bezier"
//now the class is renamed "curve"
int i;
Point2D p;
p.x=0;
p.y=0;
if( points.size() == 1 ) return points[0];
if( points.size() == 0 ) return p;
curve b;
for (i=0;i<(int)points.size()-1;i++)
{
p.x = ( points[i+1].x - points[i].x ) * x + points[i].x;
p.y = ( points[i+1].y - points[i].y ) * x + points[i].y;
if (points.size()<=2) return p;
b.PushPoint2D(p);
}
return b.GetPoint(x);
}
//THIS IS NEW AND VERY VERY COOL
double curve::LagrangeInterpolation(double x)
{
double y = 0;
for (int i = 0; i <= (int)points.size()-1; i++)
{
double numerator = 1;
double denominator = 1;
for (int c = 0; c <= (int)points.size()-1; c++)
{
if (c != i)
{
numerator *= (x - points[c].x);
denominator *= (points[i].x - points[c].x);
}
}
y += (points[i].y * (numerator / denominator));
}
return y;
}
curve::~curve(void)
{
}
double GetLogicalYAtX(double x)
{
curve cv;
Point2D p;
p.x=0; //always left edge
p.y=y1; //now by var
cv.PushPoint2D(p);
p.x=x2; //now by var
p.y=y2; //now by var
cv.PushPoint2D(p);
p.x=1; //always right edge
p.y=y3; //now by var
cv.PushPoint2D(p);
//p=cv.GetPoint(x);
//return p.y;
return cv.LagrangeInterpolation(x);
}
Do you have any ideas how I could get the new solution a little bit more "soft"? So that I can move the 2. Point in larger areas without the curve going out of boundaries? Thank you
static bezier From3Points(const Point2D &a, const Point2D &b, const Point2D &c)
{
bezier result;
result.PushPoint2D(a);
Point2D middle;
middle.x = 2*b.x - a.x/2 - c.x/2;
middle.y = 2*b.y - a.y/2 - c.y/2;
result.PushPoint2D(middle);
result.PushPoint2D(c);
return result;
}
Untested, but should return a bezier curve where at t=0.5 the curve passes through point 'b'.
Additionally (more untested code ahead), you can calculate your points using bernstein basis polynomials like so.
static int binomialcoefficient (int n, int k)
{
if (k == 0)
return 1;
if (n == 0)
return 0;
int result = 0;
for (int i = 1; i <= k; ++i)
{
result += (n - (k - i))/i;
}
return result;
}
static double bernstein (int v, int n, double t)
{
return binomialcoefficient(v,n) * pow(t,v) * pow(1 - t,n - v);
}
Point2D GetPoint (double t)
{
Point2D result;
result.x = 0;
result.y = 0;
for (int i = 0; i < points.size(); ++i)
{
double coeff = bernstein (i,points.size(),t);
result.x += coeff * points[i].x;
result.y += coeff * points[i].y;
}
return result;
}