AMCAX Kernel 1.0.0.0
A Geometric Constraint Solver Sample

Overview

This tutorial provides the basic usage of AMCAX geometric constraint solver.

Required Knowledge

The developers need to have some basic knowledge including the modern C++ programming language, 3D geometric modeling concepts. In specific, the AMCAX GCS is designed by using C++ 17 standard, and STL containers and algorithms are used as basic data structures and utilities.

Sample of 3D geometric constraint solver

Result Preview

This sample uses two cubes to show the solving capabilities of the AMCAX GCS. The result is shown in the figure below:

Constrained cubes

There are two constraints between the cubes:

  1. The distance between vertex P and edge L1 is 2.
  2. The distance between edge L and edge L2 is 1.5.

We will introduce how to construct constraint relationships between geometries and obtain the solution.

Construct geometric constraints

Create rigid bodies

The first step is to create rigid bodies that represent the two cubes.

auto gcsSystem = std::make_shared<AMCAX::GCS::GCSWSystem>();
auto rigidBody1 = gcsSystem->CreateRigidBody(1);
auto rigidBody2 = gcsSystem->CreateRigidBody(2);

Create geometric entities

Next create the geometric entities related to the geometric constraints.

auto createPoint = [](double x, double y, double z)->AMCAX::GCS::Point3d {
point.x = x;
point.y = y;
point.z = z;
return point;
};
auto createVector = [](double x, double y, double z)->AMCAX::GCS::Vector3d {
vector.x = x;
vector.y = y;
vector.z = z;
return vector;
};
auto createLine = [](const AMCAX::GCS::Point3d& origin, const AMCAX::GCS::Vector3d& direction)->AMCAX::GCS::Line3d {
line.origin = origin;
line.direction = direction;
return line;
};
Line represented by a point and the normalized direction vector.
Definition: AMCAXGCS.h:54
Point3d origin
A point on the line.
Definition: AMCAXGCS.h:58
Vector3d direction
Normalized line direction vector.
Definition: AMCAXGCS.h:62
Point.
Definition: AMCAXGCS.h:36
Vector.
Definition: AMCAXGCS.h:45

First create points and lines representing P and L1.

auto pointCube1 = createPoint(1.2470916419629932, 0.23514982144115493, -5.820766091346741e-11);
auto line1Cube2 = createLine(createPoint(2.5834565193285233, 0.3538446011985319, -5.8207660913467394e-11), createVector(0.0, -1.0, 0.0));

Then create two lines representing L and L2.

auto lineCube1 = createLine(createPoint(1.2470916419629932, 0.6242608214411551, 0.9999999999417923), createVector(0.0, 1.0, 0.0));
auto line2Cube2 = createLine(createPoint(2.5834565193285233, 0.3538446011985319, 0.9999999999417923), createVector(0.0, -1.0, 0.0));

Create constraints

Now we can create constraints between geometric entities.

First, we create the distance constraint between P and L1, and pass the geometric entity and the rigid body where the constraint relationship exists as parameters into GCSSystem.

gcsSystem->Create3dDistPtLn(conHandle1, rigidBody1, rigidBody2, pointCube1, line1Cube2, 2);
The wrapper for GCSConHandle.
Definition: AMCAXGCS.h:221

Then we create the distance constraint between L and L2 in the same way.

gcsSystem->Create3dDistLnLn(conHandle2, rigidBody1, rigidBody2, lineCube1, line2Cube2, 1.5, AMCAX::GCS::kParallel);
kParallel
Do not specify direction*‍/.
Definition: AMCAXGCS.h:161

Solve geometric constraints

Solve

After completing the construction of the constraint relationships, we can solve the rigid body transformation to satisfy the above constraints.

auto result = gcsSystem->Solve();

Get updated entity

If the solver returns AMCAX::GCS::Status::kSolved, the following is an example of obtaining a geometric entity that satisfies the constraint relationship.

// update point on cube1
pointCube1 = gcsSystem->UpdatePoint3dPosition(rigidBody1, pointCube1);
// update line on cube1
lineCube1 = gcsSystem->UpdateLine3dPosition(rigidBody1, lineCube1);
// update the first line on cube2
line1Cube2 = gcsSystem->UpdateLine3dPosition(rigidBody2, line1Cube2);
// update the second line on cube2
line2Cube2 = gcsSystem->UpdateLine3dPosition(rigidBody2, line2Cube2);

Sample code

The complete code of this sample is listed here:

void RunDemo() {
auto gcsSystem = std::make_shared<AMCAX::GCS::GCSWSystem>();
// create rigid body for cube 1
auto rigidBody1 = gcsSystem->CreateRigidBody(1);
// create rigid body for cube 2
auto rigidBody2 = gcsSystem->CreateRigidBody(2);
auto createPoint = [](double x, double y, double z)->AMCAX::GCS::Point3d {
point.x = x;
point.y = y;
point.z = z;
return point;
};
auto createVector = [](double x, double y, double z)->AMCAX::GCS::Vector3d {
vector.x = x;
vector.y = y;
vector.z = z;
return vector;
};
auto createLine = [](const AMCAX::GCS::Point3d& origin, const AMCAX::GCS::Vector3d& direction)->AMCAX::GCS::Line3d {
line.origin = origin;
line.direction = direction;
return line;
};
// create point on cube 1
auto pointCube1 = createPoint(1.2470916419629932, 0.23514982144115493, -5.820766091346741e-11);
// create first line on cube 2
auto line1Cube2 = createLine(createPoint(2.5834565193285233, 0.3538446011985319, -5.8207660913467394e-11), createVector(0.0, -1.0, 0.0));
// create line on cube 1
auto lineCube1 = createLine(createPoint(1.2470916419629932, 0.6242608214411551, 0.9999999999417923), createVector(0.0, 1.0, 0.0));
// create second line on cube 2
auto line2Cube2 = createLine(createPoint(2.5834565193285233, 0.3538446011985319, 0.9999999999417923), createVector(0.0, -1.0, 0.0));
// create distance constraint between point and line
gcsSystem->Create3dDistPtLn(conHandle1, rigidBody1, rigidBody2, pointCube1, line1Cube2, 2);
// create distance constraint between two lines
gcsSystem->Create3dDistLnLn(conHandle2, rigidBody1, rigidBody2, lineCube1, line2Cube2, 1.5, AMCAX::GCS::kParallel);
// solve the constraint problem
AMCAX::GCS::Status solveStatus = gcsSystem->Solve();
if (AMCAX::GCS::Status::kSolved == solveStatus) {
// update point on cube1
pointCube1 = gcsSystem->UpdatePoint3dPosition(rigidBody1, pointCube1);
// update line on cube1
lineCube1 = gcsSystem->UpdateLine3dPosition(rigidBody1, lineCube1);
// update the first line on cube2
line1Cube2 = gcsSystem->UpdateLine3dPosition(rigidBody2, line1Cube2);
// update the second line on cube2
line2Cube2 = gcsSystem->UpdateLine3dPosition(rigidBody2, line2Cube2);
}
}

Sample of 2D geometric constraint solver

This sample uses tangent lines and circles to show the solving capabilities of the AMCAX GCS.

Construct geometric constraints

Create geometric entities

The first step is to create the geometric entities related to the geometric constraints.

A line segment is represented by two endpoints, so create the two endpoints first, and then create the line segment from the two endpoints.

gcsSystem.Create2dPoint(handlePoint0, { -63.296707, -22.307692 });
gcsSystem.Create2dPoint(handlePoint1, { -23.956042, 37.472527 });
gcsSystem.Create2dLine(handleLine, handlePoint0, handlePoint1);
The wrapper for GCSSystem.
Definition: AMCAXGCS.h:241
Status Create2dLine(GCSWVarGeomHandle &h, const GCSWVarGeomHandle &point0, const GCSWVarGeomHandle &point1)
Create a line segment in 2D.
Status Create2dPoint(GCSWVarGeomHandle &h, const Point2d &point)
Create a point in 2D.
The wrapper for GCSVarGeomHandle.
Definition: AMCAXGCS.h:168

A circle is represented by its center and radius, so create the center first, and then create the circle based on the center and radius.

gcsSystem.Create2dPoint(handleCenter, { 23.516476, -22.087912 });
gcsSystem.Create2dCircle(handleCircle, handleCenter, 39.189965);
Status Create2dCircle(GCSWVarGeomHandle &h, const GCSWVarGeomHandle &center, double radius)
Create a circle in 2D.

Create constraints

Create tangency constraints between line segments and circles. The last parameter 0 means that the distance between the line segment and the circle is 0.

gcsSystem.Create2dTanLnCir(conHandle, handleLine, handleCircle, 0);
Status Create2dTanLnCir(GCSWConHandle &h, GCSWVarGeomHandle &ln, GCSWVarGeomHandle &cir, double d)
Create a 2D tangent line/circle constraint.

Solve geometric constraints

Solve

After completing the construction of the constraint relationships, we can solve the geometric entities to satisfy the above constraint.

AMCAX::GCS::Status solveStatus = gcsSystem->Solve();
Status Solve()
General solve. Solve the constraint system.

Get updated entity

If the solver returns AMCAX::GCS::Status::kSolved, the following is an example of obtaining a geometric entity that satisfies the constraint relationship.

AMCAX::GCS::Line2d line = gcsSystem.GetLine2d(handleLine);
AMCAX::GCS::Circle2d circle = gcsSystem.GetCircle2d(handleCircle);
Circle2d GetCircle2d(const GCSWVarGeomHandle &h) const
Get circle.
Line2d GetLine2d(const GCSWVarGeomHandle &h) const
Get line.
Circle in 2d.
Definition: AMCAXGCS.h:128
Line in 2d.
Definition: AMCAXGCS.h:120

Sample code

The complete code of this sample is listed here:

void Run2DDemo() {
gcsSystem.Create2dPoint(handlePoint0, { -63.296707, -22.307692 });
gcsSystem.Create2dPoint(handlePoint1, { -23.956042, 37.472527 });
gcsSystem.Create2dLine(handleLine, handlePoint0, handlePoint1);
gcsSystem.Create2dPoint(handleCenter, { 23.516476, -22.087912 });
gcsSystem.Create2dCircle(handleCircle, handleCenter, 39.189965);
gcsSystem.Create2dTanLnCir(conHandle, handleLine, handleCircle, 0);
AMCAX::GCS::Status solveStatus = gcsSystem.Solve();
if (AMCAX::GCS::Status::kSolved == solveStatus) {
AMCAX::GCS::Line2d line = gcsSystem.GetLine2d(handleLine);
AMCAX::GCS::Circle2d circle = gcsSystem.GetCircle2d(handleCircle);
}
}