Unallow a Circle instance to accept a Point3D as center - oop

I would like to submit a OOP problem. Maybe it has been solved elsewhere, but I wasn't able to find it...
Imagine something like this (python-like pseudo-code)
class Point:
x: int
y: int
# Some methods here
class Point3D(Point):
z: int
class Circle:
center: Point
radius: int
# Some methods here
class Sphere(Circle):
center: Point3D
In a staticly typed langage - unless I make a mistake - a Point3D instance will pass as a center attribute for Circle, since it inherits from Point, wich has to be unallowed, because it would turn into a Sphere-like.
How can we achieve that without losing methods factorisation?

The Liskov Substitution Principle (LSP) states that replacing an instance of a base classe with an instance of a derived class shall always work. This is a core feature of OOP, not an issue.
The issue is in you model -- let's consider what the relationship between a 2D point and a 3D point is. Having Point3D inherit from Point2D states that a Point3D is a Point2D, that is, all Point3D's are also Point2D's.
But this does not actually fit what you're modeling! In math, only 3D points from the 2D plane (the ones with z == 0) are actually 2D points. This discrepancy is the source of that loophole that might turn your Circle into a sphere.
The OOP model for this could actually be the opposite: all 2D points are 3D points, with z == 0. Thus Point2D inheriting from Point3D would kind of make sense. It would, however, open up a new set of problems with mutability: if you are able to access a Point2D as a Point3D and modify it, then you can set its z coordinate to be non-zero, and end up with an inconsistent Point2D that is not actually 2D anymore. LSP is broken again.
It is tempting to represent the relationship between a 2D and a 3D point in OOP in either direction:
A 3D point contains one more coordinate that a 2D point doesn't use, thus it should be the derived class
... or...
Mathematically, a 2D points is also a 3D point, so it should be the derived class
... but the bottom line is simply that neither class can inherit from the other one, because the LSP is broken either way. Keep them as separate classes, apples with apples and Circles with Point2Ds, and use some other language features if you need to factor common code between points -- generic programming, for example.

Related

How to Create a List of Vectors Using the Curve Class Traveling from A to B?

I'm trying to create a path for an object to travel by.
I want the path to use a curve that goes upwards from the start(A) to then fall down to the bottom(B).
Like this :
I've looked at different ways to create a curved path and they all either use the Spritebatch to create the curve or don't use the Curve class. I need to create many curves in parallel to be used by many different sprites with each their own curve.
So i looked at the Microsoft.Xna.Framework.Curve class but i can't find any good resource for how to use it correctly.
The Curve class uses CurveKey for its points but it's unclear exactly how you convert a Key to a Vector2D as a key is defined in a Single numeric value and not a XY coordinate.
I want a SortedList of all the points that are needed for a Sprite to travel with the Curve that i can use with the Vector2D class but again, i don't really understand how to use the Curve class, and the documentation is rather confusing.
It talks about that if you want more dimensions you can use multiple Curve objects but there isn't an example on there.
I have not been able to get the CurveEditor to compile either and support for it seems to be long dead.
If anyone could show me how to make a curve with the Curve class and have that translate into a coordinate with Vector2D that would be a great starting point.
The Vector2 class has a static method defined as:
public static Vector2 Hermite(Vector2 value1, Vector2 tangent1, Vector2 value2, Vector2 tangent2, float amount)
This is similar to a lerp, where the amount is a number between 0 and 1.

How can unit quaternions represent attitude?

I'm reading a paper the presents a quaternion based complimentary filter but I'm confused on how and why they represent the attitude of an object with a single quaternion denoted by "q" in the paper. I thought that a unit quaternion represents a rotation like a rotation matrix and is defined as an operator. For example to rotate a vector v... v_f=q(v_0)q^-1
In the paper they state "If the device has an attitude q at time t, the attitude at the subsequent time-step t + dt, is denoted q′"
How can an object have an attitude q?
They probably misuse the word attitude. What they mean by attitude is the orientation of an object.
The orientation is usually defined in physics as a frame made of three orthogonal vectors.
You can also define the orientation as a rotation matrix but that forces you to choose a coordinate system. Other way is to use a quaternion, which is an algebraic entity like a vector (and thus coordinate-free).
Hope that helps.

How to choose control point distance for 3D cubic Bézier curves to optimize 'roundness'?

Say I want to construct a 3D cubic Bézier curve, and I already have both end-points, and the direction (normal vector) for both control points. How can I choose the distance of both control points to their respective end-points in order to make the curve as 'nicely rounded' as possible?
To formalize 'nicely rounded': I think that means maximizing the smallest angle between any two segments in the curve. For example, having end-points (10, 0, 0) and (0, 10, 0) with respective normal vectors (0, 1, 0) and (1, 0, 0) should result in a 90° circular arc. For the specific case of 2D circular arcs, I've found articles like this one. But I haven't been able to find anything for my more general case.
(Note that these images are just to illustrate the 'roundness' concept. My curves are not guaranteed to be plane-aligned. I may replace the images later to better illustrate that point.)
This is a question of aesthetics, and if the real solution is unknown or too complicated, I would be happy with a reasonable approximation. My current approximation is too simplistic: choosing half the distance between the two end-points for both control point distances. Someone more familiar with the math will probably be able to come up with something better.
(PS: This is for open-source software, and I would be happy to give credit on GitHub.)
Edit: Here are some other images to illustrate a 3D case (jsfiddle):
Edit 2: Here's a screenshot of an unstable version of ApiNATOMY to give you an idea of what I'm trying to do. I'm creating 3D tubes to represent blood-vessels, connecting different parts of an anatomical schematic:
(They won't let me put in a jsfiddle link if I don't include code...)
What you are basically asking is to have curvature over the spline as constant as possible.
A curve with constant curvature is just a circular arc, so it makes sense to try to fit such an arc to your input parameters. In 2D, this is easy: construct the line which goes through your starting point and is orthogonal to the desired direction vector. Do the same for the ending point. Now intersect these two lines: the result is the center of the circle which passes through the two points with the desired direction vectors.
In your example, this intersection point would just be (0,0), and the desired circular arc lies on the unit circle.
So this gives you a circular arc, which you can either use directly or use the approximation algorithm which you have already cited.
This breaks down when the two direction vectors are collinear, so you'd have to fudge it a bit if this ever comes up. If they point at each other, you can simply use a straight line.
In 3D, the same construction gives you two planes passing through the end points. Intersect these, and you get a line; on this line, choose the point which minimizes the sum of squared distances to the two points. This gives you the center of a sphere which touches both end points, and now you can simply work in the plane spanned by these three points and proceed as in 2D.
For the special case where your two end points and the two known normal vector for the control points happen to make the Bezier curve a planar one, then basically you are looking for a cubic Bezier curve that can well approximate a circular arc. For this special case, you can set the distance (denoted as L) between the control point and their respective end point as L = (4/3)*tan(A/4) where A is the angle of the circular arc.
For the general 3D case, perhaps you can apply the same formula as:
compute the angle between the two normal vectors.
use L=(4/3)*tan(A/4) to decide the location of your control points.
if your normals are aligned in a plane
What you're basically doing here is creating an elliptical arc, in 3D, where the "it's in 3D" part is completely irrelevant, since it's just a 2D curve, rotated/translated to sit in your 3D space. So let's just solve the 2D case, and then the RT is entirely up to you.
Creating the "perfect" cubic Bezier between two points on an arc comes with limitations. You basically can't create good looking arcs that span more than a quarter circle. So, with that said: your start and end point normals give you a 2D angle between your normal vectors, which is the same angle as between your start and end tangents (since normals are perpendicular to tangents). So, let's:
align our curve so that the tangent at the start is 0
plug the angle between tangents into the formula given in the section on Circle approximation in the Primer on Bezier curves. This is basically just dumb "implementing the formula for c1x/c1y/c2x/c2y as a function that takes an angle as argument, and spits out four values as c1(x,y) and c2(x,y) coordinats".
There is no step 3, we're done.
After step 2, you have your control points in 2D to create the most circular arc between a start and end point. Now you just need to scale/rotate/translate it in 3D so that it lines up with where you needed your start and end point to begin with.
if your normals are not aligned in a plane
Now we have a problem, although one that we can deal with by treating the dimensions as separate things entirely. Instead of creating a single 2D curve, we're going to create three: one that's the X/Y projection, one that's the X/Z projection, and one that's the Y/Z projection. For all three of these, we're going to abstract the control points in exactly the same way as before, and then we simply take the projective control points (three for each control point), and then go "okay, we now have X, Y, and Z projective coordinates. That means we have (X,Y,Z) coordinates", and done again.

Does CGAL 2D Conforming Mesh support fix points?

In my meshing application I will have to specify fix points within a domain. The idea is that, the fix points must also be the element points after the domain is being meshed.
Furthermore, the elements around the fix points should be more dense. The general concept is that for the fix points, there should exist a radius r around those points, such that the mesh size inside r is of different sizes than outside of the r. The mesh sizes inside and outside of the r should be specifiable.
Are these two things doable in CGAL 2D Mesh algorithm?
Using your wording, all the input point of the initial constrained Delaunay triangulation will be fix points, because the 2D mesh generator only insert new points in the triangulation: it never removes any point.
As for the density, you can copy, paste, and modify a criteria class, such as CGAL::Delaunay_mesh_size_criteria_2<CDT> so that the local size upper bound is smaller around the fix points.
Now, the difficulty is how to implement that new size policy. Your criteria class could store a const reference to another Delaunay_triangulation_2, that contains only the fixed points you want. Then, for each triangle query, you can call nearest_vertex and then actually check if the distance between the query point is smaller that the radius bound of your circles. For a triangle, you can either verify that for only its barycenter, or for all three points of the triangle. Then, according to the result of that/those query(s), you can modify the size bound, in the code of your copy of CGAL::Delaunay_mesh_size_criteria_2<CDT>.
Yes, no points will be removed from the triangulation by the mesher.
Note however that if you insert points too close to a constraint this will induce a refinement of the constraint while it is not Gabriel.

How should I implement a class representing a geometric plane?

In a given domain, I need to represent mathematical plane in 3D space, so I intend to create a Plane3D class.
I would also have Point3D, Vector3D, Ray3D, and so on. Main use case would be to test/find line-plane intersections, line-plane angles, and other geometric operations.
Question is:
Which would be a good, canonical, computation-friendly way to implement plane definition in a class?
Most obvious candidates would be "point-normal" form, with six numeric parameters (three coordinates for the point, three for the vector) and "general (algebraic) form", with four numeric parameters (one coefficient per coordinate and one constant). Is one of them computationally preferrable?
Also, is there any open source, high level 3D Geometry library already implementing this class, which would be worth taking a look for inspiration?
OBS: Since .NET has System.Windows.Media.Media3D library with some useful classes, most probably I'll implement this in C#, taking advantage of Point3D and Vector3D structs, but I think the question is language-agnostic.
I'd go for what you call algebraic form. A point (x,y,z) is on a plane (a,b,c,d) if a*x+b*y+c*z+d=0.
To intersect that plane with a line spanned by (x1,y1,z1) and (x2,y2,z2), compute s1=a*x1+b*y1+c*z1+d and s2=a*x2+b*y2+c*z2+d. Then your point of intersection is defined by
x=(s1*x2-s2*x1)/(s1-s2)
y=(s1*y2-s2*y1)/(s1-s2)
z=(s1*z2-s2*z1)/(s1-s2)
To compute the angle between a line and a plane, simply compute
sin(α)=(a*x+b*y+c*z)/sqrt((a*a+b*b+c*c)*(x*x+y*y+z*z))
where (a,b,c) represents the normal vector in this representation of the plane, and (x,y,z) is the direction vector of the line, i.e. (x2-x1,y2-y1,z2-z1). The equation is essentially a normalized dot product, and as such is equivalent to the cosine between the two vectors. And since the normal vector is perpendicular to the plane, and sine and cosine differ by 90°, this means that you get the sine of the angle between the line and the plane itself.