delete node while preserving shape
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Inkscape |
New
|
Undecided
|
Unassigned |
Bug Description
When Inkscape deletes a node and tries to preserve the shape of the Bezier, the new shape is usually poor. Fundamentally, we are attempting to collapse 10 degrees of freedom (4 handles + 1 position) into 4 degrees of freedom (2 handles). Here are some conditions that the current algorithm fails:
1. It's not the inverse of node addition. If you add a node and then delete it, the path should be the original path. That isn't true at the moment.
2. It's not symmetric. If nodes A, B, and C are along a path in that order, and node B is deleted, the produced path should be the same as if nodes B, C, and A are along a path in that order.
If this is unclear, then take a rectangle, convert it to a path, and then choose a node and delete it. The created path will be different for adjacent nodes. That makes no sense.
These two conditions apply to any optimal algorithm. But after that, further conditions are mostly arbitrary. We can take some hints from the node addition algorithm, and impose an extra condition:
3. The remaining nodes in the new curve preserve their handle directions.
There is no reason why feature 3 is optimal, and there are probably a few ways to be "optimal". However, there are a few good reasons to choose feature 3:
It's clear what the product will look like, before performing the operation.
The user often desires to preserve handle directions.
Node addition also preserves handle directions.
Smooth nodes are kept smooth.
So we might as well have feature 3 in the absence of any other good ideas. After that, we only have two degrees of freedom left, which are the handle lengths. Some extra constraints are needed. I can give some further ideas:
4. Commutativity; deleting point A and then B is the same as deleting B and then A.
5. The new curve passes through the original point. But this doesn't completely specify the handle lengths. And it means the operation is automatically noncommutative.
6. The curvature of the new curve is equal to the curvature of the old curves at the remaining nodes. Note that 6 implies 4.
My guess is that 6 will probably give the best result. But it's only a guess; I don't know anything about Beziers.
tags: | added: 2geo |
tags: |
added: 2geom removed: 2geo |
tags: | added: node-editing |
summary: |
- delete node shape + delete node while preserving shape |
Note: Option 6 sometimes requires the handles to be flipped in the other direction.
This code attempts to use Option 6 with Geom::cubics_ fitting_ curvature( ) but doesn't work. Apparently there can be 4 possible beziers according to Geom::cubics_ fitting_ curvature( ), but I don't know if it's using signed or unsigned curvature; signed is appropriate. Also, there seems to be a convention change, because the derivative of the endpoint points in the opposite direction it should be unless I write "derivatives_ at_end[ 1] = -derivatives_ at_end[ 1];".
I have no idea why, and I no longer have the motivation to figure out what it's trying to do. Here's the state of the code before I stopped caring.