Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IfcPolynomialCurve #539

Open
wants to merge 20 commits into
base: development
Choose a base branch
from

Conversation

Elvira2227
Copy link
Collaborator

@Elvira2227 Elvira2227 commented Apr 16, 2022

In this pull request implementation was added for IfcPolynomialCurve.
The following functions were added in CurveConverter.h:

  1. getPointOnCurve
  2. getDirectionOfCurve - here we need to implement additional code in covertIfcCurveSegment to calculate rotation around x,y axis and also rotation in 3D. Now we can only rotate around axis z.
  3. calculatePolynomialCurve - to calculate polynomial from coefficietnts

For explanation there is a screen shot of cubic curve with coefficientsX (0., 1., 0.) and coefficientsY (0., 0., 0.01, 0.).

image

Note:
This is related to #524
Please see starting from commit 2b83b5b

@Elvira2227 Elvira2227 requested review from pjanck and jschlenger April 16, 2022 12:23
@Elvira2227 Elvira2227 self-assigned this Apr 16, 2022
@Elvira2227 Elvira2227 added enhancement New feature or request IFC Content related to Industry Foundation Classes (IFC) functionalities labels Apr 16, 2022
Copy link
Contributor

@pjanck pjanck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General remarks:

  • some unit tests are still missing a screen shot
  • it seems weird to have so many unit tests for line that seem all equal
  • some png are not needed as they are not used in checking

buw::storeImage(testPath("bloss-curve_100.0_300_1000_1_Meter.png").string(), image);

// Assert
EXPECT_NO_THROW(buw::loadImage4b(testPath("bloss-curve_100.0_300_1000_1_Meter.png").string()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't seem to see this file commited.

buw::Image4b image = rendererIfc->captureImage();

// Act
buw::storeImage(testPath("clothoid_100.0_1000_-300_1_Meter.png").string(), image);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file with this name does not need be committed (only the top view is needed for these unit tests). Apply for all unit tests.

Copy link
Collaborator

@jschlenger jschlenger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really not sure if your angle calculation is right.
Please double check and test with break points if the produced values make sense.

Comment on lines 2975 to 2980
if (polynomialConstantCntX>0 && polynomialConstantCntY>0)
{
double angle = std::atan2(angleY, angleX);
return carve::geom::VECTOR(std::cos(angle), std::sin(angle), 0.);

}
Copy link
Collaborator

@jschlenger jschlenger May 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that you need to insert angleX and angleY here?
From a quick view it would feel more natural to insert pointX and pointY into atan to get an angle than using two angles to get another angle.
Please take a closer look here to see if what you've done produces the results that you expect.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are right.
I thought that we can find separatelly the angles for X and Y polynomial. Thats why I used the same function from SpiralUtils as for the clothoids.
My suggestion to use the implementation from this sourse : https://firebirdsql.org/refdocs/langrefupd21-intfunc-atan2.html
Then we can use atan2(sin(angleY), cos(angleX)).
See cf59b36

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tasted different cases and this is a result that presents the first data of vector segmentDirections

angle = atan2(std::sin(angleY),std::cos(angleX));
carve::geom::vector<3> v1 = carve::geom::VECTOR(std::cos(angle), std::sin(angle), 0. );

[0]:{1.0000000000000000, 0.0000000000000000, 0.0000000000000000}- corresponds to point (0,0,0)
[1]:{0.93699400295766744, 0.34934544282324143, 0.0000000000000000}
[2]:{-0.67306627244558215, 0.73958217453925257, 0.0000000000000000}
...
angle = atan2(y,x);
carve::geom::vector<3> v2 = carve::geom::VECTOR(std::cos(angle), std::sin(angle), 0. );

[0]:{1.0000000000000000, 0.0000000000000000, 0.0000000000000000} - corresponds to point (0,0,0)
[1]:{0.78609999999999047, 0.61795320999998504, 0.0000000000000000}
[2]: {1.2495999999999947, 1.5615001599999867, 0.0000000000000000}
...

It only says that we have similar values for different calculations. Interestingly, our rotation matrix uses only the first point (segmentDirections[0]) to detect the direction. I think this should be the next task to check over.

P.S: I decided to place your suggestion about angle calculations.

@Elvira2227
Copy link
Collaborator Author

Elvira2227 commented May 12, 2022

There are several changes in the last commits cf59b36 and 28f6421.

  • First, I was trying to find corresponding functions from the SpiralUtils, but it returned high values of X and Y. Thats why I desided to write a separate functions which calculates integral by using numerical methods. That will helps to find appropriate values for X and Y.
  • New functions integrateParameter , calculatePolynomialDerivative, intagral have been placed in CurveConverter.h.
  • I have noticed that integrateParameter returned the value with the approximation error 0.4%.
  • In the commit 28f6421 are small corrections for integrateParameter function.
  • I tested my code with polynomialConstantX = (0.,1.,0.) and polynomialConstantY = (0.,0.,1., 0.)

Here is the implemented polycurve:
image

@Elvira2227 Elvira2227 requested review from pjanck and jschlenger May 12, 2022 15:47
Copy link
Contributor

@pjanck pjanck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some suggestions :)

@Elvira2227 Elvira2227 requested a review from pjanck May 27, 2022 16:00
Copy link
Contributor

@pjanck pjanck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to review the code more thoroughly, just one quick comment.

@Elvira2227 Elvira2227 requested a review from pjanck May 29, 2022 11:11
Copy link
Collaborator

@jschlenger jschlenger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor comments here and there

// calculate angle between two polynomial curves
//double angle = std::atan2(angleY, angleX);

if (polynomialConstantCntX>0 && polynomialConstantCntY>0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the polynomialConstantCnt only used for these if clauses?
If that's the case one could save a couple of lines by just writing
if (polynomialCurve->CoefficientsX && polynomialCurve->CoefficientsY)
then the polynomialConstCnt could be removed completely
However, this is just a personal preference and can also be left the way it is right now

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use polynomialConstantCntXYZ to check if the coefficients exist.
Because in the beginning, I create polynomialConstantXYZ vectors and then check it in this if statement it should always return true.
If polynomialConstantXYZ exist and its size polynomialConstantCntXYZ return positive value.

Comment on lines 3040 to 3051
if (polynomialCurve->CoefficientsX)
{
// Interpret coefficients for X
coefficientsX = polynomialCurve->CoefficientsX;
// convert to double
polynomialConstantX.resize(coefficientsX.size());
std::transform(coefficientsX.begin(), coefficientsX.end(), polynomialConstantX.begin(), [](auto it) { return it; });
polynomialConstantCntX = std::size(polynomialConstantX);
//x = SpiralUtils::XbyAngleDeviationPolynomial(polynomialConstantX, polynomialConstantCntX, parameter);
//x = SpiralUtils::XbyAngleDeviationPolynomialByTerms( 0., 0., 0., 0., 0., 0., 1., 0., parameter);

}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it make sense to put this coefficient x y z retrieval into a separate function that is then called by getPointOnCurve and by getDirectionOfCurve?
Looks like the same code is used at least twice which could be avoided

Copy link
Contributor

@pjanck pjanck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not there yet, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request IFC Content related to Industry Foundation Classes (IFC) functionalities
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants