elastic stretching or bending

Use this forum to ask questions about how to do things in QCAD.

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files and screenshots.

Post one question per topic.

Post Reply
rui_fartaria
Newbie Member
Posts: 4
Joined: Wed Jul 29, 2020 7:48 pm

elastic stretching or bending

Post by rui_fartaria » Wed Jul 29, 2020 7:58 pm

Hello,
I could not find anything in the forum or manual about this.

Are there any transforms implemented that allow to stretch or bend a polyline according to an elastic function across the line.

What I mean is, I want to to be able to pick the end of the line and drag it so that the full polyline is transformed with decreasing intensity as distance increases (along the line) from the end of the line.

Also, this would be valid for any point of the polyline.

Thank you in advance for your attention.

User avatar
Husky
Moderator/Drawing Help/Testing
Posts: 4939
Joined: Wed May 11, 2011 9:25 am
Location: USA

Re: elastic stretching or bending

Post by Husky » Wed Jul 29, 2020 9:04 pm

Hi
rui_fartaria wrote:
Wed Jul 29, 2020 7:58 pm

Are there any transforms implemented that allow to stretch or bend a polyline according to an elastic function across the line.
You can't "bend" a polyline but you can "bend" a spline ...
rui_fartaria wrote:
Wed Jul 29, 2020 7:58 pm
What I mean is, I want to to be able to pick the end of the line and drag it so that the full polyline is transformed with decreasing intensity as distance increases (along the line) from the end of the line.
You can design a polyline with a start width of ... let say zero and an end width of 25. If you then drag the end it will behave like a rubber line ... :wink:
Work smart, not hard: QCad Pro
Win10/64, QcadPro, QcadCam version: Current.
If a thread is considered as "solved" please change the title of the first post to "[solved] Title..."

rui_fartaria
Newbie Member
Posts: 4
Joined: Wed Jul 29, 2020 7:48 pm

Re: elastic stretching or bending

Post by rui_fartaria » Wed Jul 29, 2020 9:50 pm

HI,
I was trying to experiment with the behaviour you explained (progressive width) but could not see it. Only the last segment moved. Not the whole polyline.

I will have to implement this myself. If I succeed i'll try to make it available as a script/macro.

Thanks.

CVH
Premier Member
Posts: 3474
Joined: Wed Sep 27, 2017 4:17 pm

Re: elastic stretching or bending

Post by CVH » Thu Jul 30, 2020 7:10 am

Very interesting,
Keep us posted. :wink:
Regards,
CVH

rui_fartaria
Newbie Member
Posts: 4
Joined: Wed Jul 29, 2020 7:48 pm

Re: elastic stretching or bending

Post by rui_fartaria » Wed Aug 05, 2020 2:08 pm

What I have so far....

paste this into the ecmascript console or run it as a script.

it will:
1. create a horizontal polyline from x=0 to x=100 with 100 vertices
2. will "bend" left tip with offset (20,20)
2. will "bend" rigth tip with offset (-20,20)

This bending model uses exponential decay. I've been experimenting with others but this is the best I found for my objectives. If anyone can tell about any literature on this (plastic bending mathematical models) I would very much appreciate it.

Final result should be:
https://pasteboard.co/JkXBUm8.png

The script:

Code: Select all

function makeExponentialDecay(factor) {
    return function (length) {
        var r = Math.exp(-factor*length);
        return r < 0.001 ? 0.0 : r;
    }
}

function makeExponentialDecayFullLine(lineLength) {
    var factor = 3 * Math.log(10) / lineLength;  // weight = 1.0E-3 at farthest point
    return makeExponentialDecay(factor);
}


// /**
//  * @param {RPolyLineEntity} polyLineEntity 
//  * @param {number} ivertex 
//  * @param {function (length)} weightsFunc 
//  * @param {RVector} offset 
//  */
function polylinePlasticBending(polyLineEntity, ivertex, weightsFunc, offset) { 
    var nvertex = polyLineEntity.countVertices();
    if (ivertex !== 0 && ivertex !== nvertex-1 ) {
        throw "Not implemented!";
    }

    var vertices = polyLineEntity.getData().getVertices();
    var lengths = [];
    var i;
    for (i=0; i<nvertex-1; i++) {
        lengths.push(polyLineEntity.getSegmentAt(i).getLength());
    }

    for (i=nvertex-1; i>=0; i--) {
        polyLineEntity.removeLastVertex();
    }

    if (ivertex === 0) {
        // first vertex
        var weight = weightsFunc(0.0);
        var newVertex = vertices[0].operator_add(offset.operator_multiply(weight));
        polyLineEntity.appendVertex(newVertex);

        var d0 = 0.0;
        for (i=1; i<nvertex; i++) {
            d0 += lengths[i-1];
            var weight = weightsFunc(d0);
            var newVertex = vertices[i].operator_add(offset.operator_multiply(weight));
            polyLineEntity.appendVertex(newVertex);
        }
    } else if (ivertex === nvertex-1) {
        var d0 = 0.0;
        for (i=0; i<nvertex-1; i++) d0 += lengths[i];

        // first vertex
        var weight = weightsFunc(d0);
        var newVertex = vertices[0].operator_add(offset.operator_multiply(weight));
        polyLineEntity.appendVertex(newVertex);
        
        for (i=1; i<nvertex; i++) {
            d0 -= lengths[i-1];
            var weight = weightsFunc(d0);
            var newVertex = vertices[i].operator_add(offset.operator_multiply(weight));
            polyLineEntity.appendVertex(newVertex);
        }
    } else {
        throw "Not implemented!";
    }

    var op = new RModifyObjectOperation(polyLineEntity);    
    var transaction = this.getDocumentInterface().applyOperation(op);

    return transaction;
}


//  *** begin operations

var doc = this.getDocument();
var di = this.getDocumentInterface();

var vertices = [];
for (i=0;i<100;i++) vertices.push([i*1,0,0]);
addPolyline(vertices, false);

// find out ID of polyline, that was added to the document:
var ids = doc.queryAllEntities();
for (var i=0; i<ids.length; ++i) {
    var id = ids[i];
    var entity = doc.queryEntity(id);
    if (isPolylineEntity(entity)) {
        plp = entity;
        break;
    }
}

var transaction = polylinePlasticBending(plp, 0, makeExponentialDecayFullLine(plp.getLength()), new RVector(20,20,0));
// find out ID of polyline, that was added to the document:
var ids = transaction.getAffectedObjects();
for (var i=0; i<ids.length; ++i) {
    var id = ids[i];
    var entity = doc.queryEntity(id);
    if (isPolylineEntity(entity)) {
        plp = entity;
        break;
    }
}
var r = polylinePlasticBending(plp, plp.countVertices()-1, makeExponentialDecayFullLine(plp.getLength()), new RVector(-20,20,0)); 

Post Reply

Return to “QCAD 'How Do I' Questions”