Tutorial: Automatic design of connecting solids between 2 solid geometries
Prof. Dr. Tim C. Lueth, Professor at Technical University of Munich, MIMED - Department of Mechanical Engineering, Munich, August 2025
We are already familiar with the "SGofCPLz" function, which extrudes a body in the Z direction from a contour, and "SGofCPLextrude," which allows the X or Y axis to be used instead of the Z axis. We are also familiar with the "SGofCPLcontour" function, which extends closed contours to form an extruded closed contour with a cross-section.
Now we want to connect two existing bodies directly to a third body. Here is an overview of the possibilities:
We want a straight rod from one point to another point in space We use an asymmetrical profile as the cross-section, e.g. CPLsample(32), which is not centered around the zero point and is not symmetrical.
CPLsample(32); CPL=ans; VLplot([P1;P2],'b-',3); view(-30,30);
SG0=SGsphere(5,'','','');SG1=SGtransP(SG0,P1);SG2=SGtransP(SG0,P2); SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
Extrusion of a contour along a straight line between P1 and P2
We now extrude the contour along the path from P1 to P2. To do this, we convert the two points into two frames that have the ez vector in the direction of the straight line and obtain the desired result We use the "SGof2T" function for this
T1=TofPez(P1,P2-P1), T2=TofPez(P2,P2-P1)
0.7687 0 0.6396 10.0000
-0.5322 0.5547 0.6396 0
-0.3548 -0.8321 0.4264 0
0 0 0 1.0000
0.7687 0 0.6396 40.0000
-0.5322 0.5547 0.6396 30.0000
-0.3548 -0.8321 0.4264 20.0000
0 0 0 1.0000
SGof2T(T1,T2,'','',CPL)
ans =
VL: [21×3 double]
FL: [38×3 double]
Tname: {'B' 'F'}
T: {[4×4 double] [4×4 double]}
TFiL: {[] []}
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
We see that the zero point of the contour CPL runs along the connection from P1 to P2. In this case, the path lies on the outside of the contour because it is not centered around [0 0].
If we extrude a centered square, the path from P1 to P2 lies inside the contour.
SGof2T(T1,T2,'','',PLsquare(5))
ans =
VL: [12×3 double]
FL: [20×3 double]
Tname: {'B' 'F'}
T: {[4×4 double] [4×4 double]}
TFiL: {[] []}
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
Extrusion of a contour along a path from T1 to T2
The "SGof2T" function we just used does not actually expect a connection of points, but rather of frames with an ez orientation along the path If we now draw a connection between P1 and P2 again, but the ez orientation should point upwards (ez=[0 0 1]) in both cases at P1 and P2, we obtain a new connection body that penetrates itself slightly. The reason is that the curvature of the path is tighter than the diameter of the contour in the direction of curvature.
SGof2T(TofP(P1),TofP(P2),'','',CPL); view(10,9); VLFLplotlight(0,1);
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
If we first determine a radius of curvature that is as large as the maximum diameter of the contour (sofBB(CPL)), then we obtain a meaningful but perhaps surprising path:
SGof2T(TofP(P1),TofP(P2),'',r,CPL); view(10,9); VLFLplotlight(0,1);
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
We can also reduce the radius of curvature to half the diameter, but it is better to reduce it to r=D/1.5.
SGof2T(TofP(P1),TofP(P2),'',r,CPL) ; view(10,9); VLFLplotlight(0,1);
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
We can easily imagine that, in the cross-section of CPL, the radius of curvature depends on the extent of the cross-section contour in the respective axis. The radius of curvature depends on the greatest distance of the contour points from the path in the respective direction of curvature. If the cross-section contour is not a circle, then there are different radii of curvature depending on the direction of curvature relative to the contour.
If CPL is rotated by 90 degrees, the curvature radius is larger than necessary. While the first curvature appeared to be very tight, it now appears unnecessarily large for the cross-section contour at this point At the start and end points, we see a sphere as a solid again
SGof2T(TofP(P1),TofP(P2),'',r,PLtransR(CPL,pi/2)); view(10,9); VLFLplotlight(0,1);
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
Extrusion of a contour to connect two bodies via points on surfaces
Using the functions described so far, two bodies can be connected at defined points on the surface by generating a body between these two points This is linked to the select 3D function, which allows two points to be selected interactively. Then you could draw a straight line directly between two points, but it would be at an angle to the surface and the connecting cross-section would probably not penetrate completely into the body
Complete penetration is only possible because of the position of the points in the center of the bodies
CPLsample(32); CPL=ans; VLplot([P1;P2],'b-',3); view(-30,30);
SG0=SGbar;SG1=SGtransP(SG0,P1);SG2=SGtransP(SG0,P2); SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
If the starting point is on the surface, the result is undesirable.
T1=TofPez(P1,P2-P1), T2=TofPez(P2,P2-P1)
0.7255 0 0.6882 10.0000
-0.6529 0.3162 0.6882 0
-0.2176 -0.9487 0.2294 5.0000
0 0 0 1.0000
0.7255 0 0.6882 40.0000
-0.6529 0.3162 0.6882 30.0000
-0.2176 -0.9487 0.2294 15.0000
0 0 0 1.0000
SGof2T(T1,T2,'','',CPL)
ans =
VL: [21×3 double]
FL: [38×3 double]
Tname: {'B' 'F'}
T: {[4×4 double] [4×4 double]}
TFiL: {[] []}
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
If we know the orientation of the surface and take into account that both the start direction and the end frame must point into the body when connecting, then we obtain a meaningful connection by specifying the direction vector.
T1=TofPez(P1,[0 0 1]), T2=TofPez(P2,[0 0 +1])
1 0 0 10
0 1 0 0
0 0 1 5
0 0 0 1
1 0 0 40
0 1 0 30
0 0 1 15
0 0 0 1
SGof2T(T1,T2,'',r,CPL); SG3=ans;
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
Connecting the three bodies into a solid by merging or fusion
If we now want to connect these bodies, we can do so with
SG=SGconcat({SG1,SG2,SG3})
SG =
VL: [240×3 double]
FL: [468×3 double]
FC: [468×3 double]
Tname: {'B' 'F'}
T: {[4×4 double] [4×4 double]}
TFiL: {[] []}
cla; SGplotalpha(SG,'m',0.5);
where the three bodies are independent and not connected to each other, as shown by the "SGsurfaces" function. SGofSG hides the SGconcat (Merging) function.
To merge the three bodies into one (fusion), we need the SGunion function, which does not always work when multiple edges or faces are in the same orientation. In this case, it may occasionally work (Aug. 2025).
SGunion({SG1,SG3,SG2})
ans =
VL: [250×3 double]
FL: [496×3 double]
FC: [496×3 double]
Tname: {'B' 'F'}
T: {[4×4 double] [4×4 double]}
TFiL: {[] []}
To avoid frustration, however, SGconcat should be used instead of SGunion for this task in SGLib 5.5.
Use of feature edges and feature surfaces to describe surface connections
There is often a desire to connect the closely spaced surfaces of two bodies. This can be done using the facets of the respective bodies. The basic function for straight linear connection without considering overlaps is "SGconnect2FS". The name "FS" (Feature Surface) means that there are probably other connection options if you don't want to go directly via the fi (facet indices) of the bodies.
Just to remind you:
Feature Edges (FE) are the edges whose rear surfaces exceed a defined limit angle of 90 degrees or greater. Feature Surfaces (FS) are the surfaces consisting of facets enclosed by these feature edges. The default limit angle alpha = 42.97 degrees or .76 rad.
surfacesofSG(SG1,pi/4), fil=ans; VLFLplotlight(1,0.5); textVLFS(SG1.VL,SG1.FL,fil); % textVLFS beschriftet die FS
6 Feature Surfaces found! Only the largest 99% (1..600mm^2), i.e. 6 of 6 are shown.
If you set the threshold angle for feature edges/surfaces to 90 degrees or above, there will usually only be one feature surface left.
surfacesofSG(SG1,pi/2); fil=ans; VLFLplotlight(1,0.5); textVLFS(SG1.VL,SG1.FL,fil);
1 Feature Surfaces found! Only the largest 99% (2..2200mm^2), i.e. 1 of 1 are shown.
Connection of 2 bodies via surface connections with feature surfaces
The "FSofSG" function returns the feature surfaces as a cell list instead of an index list and is easier to use.surfacesofSG(SG1,pi/4), fil=ans; VLFLplotlight(1,0.5); textVLFS(SG1.VL,SG1.FL,fil); % textVLFS beschriftet die FS
FSofSG(SG1, 'text'); FSi=ans;
FSofSG: Only 6/6 feature surfaces larger than Amin=10mm are shown! The returned surface list is always complete!
Because SG1 and S2 have the same geometry, we can simply use the same FSi for both bodies here. With this solution, there is a kink at the transition from SG1 to the new body, and also from this to SG2, which is often not useful. With this function, only surfaces that are not perpendicular to each other can be connected, or where flat bodies with zero height and volume can also be created.SGconnect2FS(SG1,SG2,FSi{2},FSi{1}); SG3=ans; textVLFS(SG1.VL,SG1.FL,fil); % (2019 - SGLib 4.7)
Then use the function to connect the three bodies againSGconcat({SG1,SG3,SG2}); % The "SGunion" function automatically switches to SGconcat if SGunion/SGbool fails.
If the bodies are further apart, we can again consider curved connections that do not contain any kinks.
CPLsample(32); CPL=ans; VLplot([P1;P2],'b-',3); view(-30,30);
SG0=SGbar;SG1=SGtransP(SG0,P1);SG2=SGtransP(SG0,P2); SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
We can achieve this if we don't want to know the exact facet index lists via frames with "TofSGFSselect" of August 2025 which is a combination of fil=FSselect(SG,varargin{:}); and [T,CPL]=TofSGfil(SG,fil);.
TofSGFSselect(SG1,[0 0 1],1); T1=ans;
Wir machen die auch mit der Endfläche und erzeugen T2
TofSGFSselect(SG2,[-1 0 0],1); T2=ans;
Now we need a list of frames TL that linearly transform T1 into T2, straighten certain sections, maintain curvature radii, and do not allow torsion or curvature of more than 45 degrees.
TLof2T(T1,T2); TL=ans;
TLadjustR: NEED TO ROTATE STARTFRAME BY -22 degree
TLadjustR: NEED TO ROTATE ENDFRAME BY -73 degree
With "SGofCPLTL" from November 2024, a contour can now be extruded along the path.
SGofCPLTL(PLsquare([3 4]),TL); SG3=ans; % Solution of 2024-Nov
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
You can also use "SGofCPLtransT" from 2018.
SGofCPLtransT(PLsquare([3 4]),TL); SG3=ans; % Solution of 2018-Aug
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
Here is a summary of how to create the path
[T1,CPL1]=TofSGFSselect(SG1,[ 0 0 1],1); % T1 and CPL1
[T2,CPL2]=TofSGFSselect(SG2,[-1 0 0],1); % T1 and CPL1
TLof2T(T1,T2); TL=ans;
TLadjustR: NEED TO ROTATE STARTFRAME BY -22 degree
TLadjustR: NEED TO ROTATE ENDFRAME BY -73 degree
Here again is the oldest solution with "SGof2T" from 2016.
SGof2T(T1,Trotate(T2,'y',pi),'',r,CPL1) % Solution of 2016
ans =
VL: [136×3 double]
FL: [268×3 double]
Tname: {'B' 'F'}
T: {[4×4 double] [4×4 double]}
TFiL: {[] []}
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
Here, for comparison, is the latest solution from 2024.
SGofCPLTL(CPL1,TL); SG3=ans; % Solution of 2024-Nov
SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
HAS TO BE COMPLETED AND DEBUGGED
dbreturn
==========================================================================================
dbreturn: EXECUTION RETURNED IN FUNCTION LiveEditorEvaluationHelperE1341057855
==========================================================================================
TLof2T(T2,'','',20); TL=ans
SGof2CPLTLcorrelate(CPLsample(7),CPLsample(8),TL); SGA=ans;
SGof2CPLTLcorrelate(CPLisccwcorrected(CPLsample(7)),CPLisccwcorrected(CPLsample(8)),TL); SGA=ans;
% SGof2CPLTLcorrelate(CPLsample(8),CPLsample(7),TL); SGA=ans;
% SGplotalpha(SG1,'r',0.5); SGplotalpha(SG2,'g',0.5);
% SGof2CPLTLcorrelate(CPL1,CPL2,TL) % 2021-March
% SGof2CVL(VLtrans(CPL1,T1), VLtrans(CPL2,T2)) % 2016-Nov OLD Style to simple
% SGof2CVL(VLtrans(CPLaddauxpoints(CPL1,1),T1), VLtrans(CPLaddauxpoints(CPL2,1),T2)) % 2016-Nov OLD Style to simple
SGcrosssectionadjustment(SG1,SG2,[0 0 1])