bugGNU Octave - Bugs: bug #47185, Improved code attached for quiver3...

 
 

bug #47185: Improved code attached for quiver3 and __quiver__ , making arrowheads actually visible:

Submitted by:  Dave Goel <deego>
Submitted on:  Thu 18 Feb 2016 05:28:05 AM UTC  
 
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Other
Status:  None Assigned to:  None
Originator Name:  Dave Goel Open/Closed:  Open
Release:  dev Operating System:  Any

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Fri 26 Feb 2016 03:52:58 PM UTC, comment #3:

Hi again Lachlan Andrew,

Thanks for responding.

(1) My bad. I have added extensive commentary now, re-tested everything, and am pasting the new code. It should be much more self-explanatory.

(2) The hg part is a much steeper learning curve for me and I have never used hg before. I have to run for an interview, but I shall put this on my todo list.

Here's the code with better commentary:

In the if(is3d) section, this code replaces this one command:

## h2 = plot3 ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
## [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
## [zarrw1.'; zend.'; zarrw2.'; NaN(1, length (z))](:),
## "linestyle", ls, "color", lc, "parent", hg);

by:

## Octave's arrowheads for the 3d case are currently a massive hack. In principle, arrowheads are a nice round cone around the arrow. But, octave's 3-D arrows were
## hitherto the usual 2-D arrowhead. This has several problems: (1) The plane in which arrowhead lies, seems, for all intents and purposes, arbitrary for every
## arrow. That confuses the user who tries to glean what's the deeper meaning about the plane. (2) Often, this plane is "into the page" plane, rendering the
## arrowhead completely invisible.

## The advantage of the hack, however, is that it's probably much faster than drawing a nice round cone. So, in keeping with the hack, we rectify the problem
## thusly: We introduce 4 arrowheads instead of 2. That pretty much guarantees at least two of them shall be visible from any angle, and the user shall always see
## an arrowhead. It is still not a nice round cone, but is much closer to the concept.
## This new code seems to take about 4 times longer than the preceding code.

xarrw3=xarrw1; yarrw3=yarrw2; ## Create arrowhead 3: use x from 1 and y from 2.
xarrw4=xarrw2; yarrw4=yarrw1; ## Create arrowhead 4: Use x from 2 and y from 1.
## Make temporary larger vectors to enable plotting within one command that can continue to be turned off or on using buttons.
## The arrowhead goes from arrowhead 1 to endpoint to arrowhead 2, and separately from arrowhead 3 to endpoint to arrowhead 4.
## But, we shall seek to do these all in one go, so we combine them vertically. We do that so that the button commands continue to work. And, hold status doesn't intervene.

xarrw13=[xarrw1(:); xarrw3(:)]; ## Combine arrows 1 and 3 vertically, call it 13.
yarrw13=[yarrw1(:); yarrw3(:)]; ##
zarrw13=[zarrw1(:); zarrw1(:)];

xarrw24=[xarrw2(:); xarrw4(:)]; ## Combine arrows 2 and 4 vertically, calli it 24.
yarrw24=[yarrw2(:); yarrw4(:)];
zarrw24=[zarrw2(:); zarrw2(:)];

nans2=NaN(1,2*length(xend)); ## Nans are needed to "lift the pen" when drawing. Double the nans since we now have double the arrowheads.

xend11=[xend(:); xend(:)]; ## Duplicate xend to plot double the number of arrows in one command.
yend11=[yend(:); yend(:)];
zend11=[zend(:); zend(:)];

h2 = plot3 ( ...
[xarrw13(:), xend11(:), xarrw24(:), nans2(:)]' ,
[yarrw13(:), yend11(:), yarrw24(:), nans2(:)]' ,
[zarrw13(:), zend11(:), zarrw24(:), nans2(:)]' ,
"linestyle", ls, "color", lc, "parent", hg);

Dave Goel <deego>
Fri 26 Feb 2016 02:43:18 PM UTC, comment #2:

Thanks, Dave. It does look better.

The code is slightly cryptic, with the 1s, 2s, 3s and 4s. Could you please provide a patch (from diff) or changeset (from Mercurial) with this change and an explanatory comment?

Lachlan Andrew <lachlan>
Thu 18 Feb 2016 05:48:39 AM UTC, comment #1:

For examples of annoying "missing" arrows in this and other images,

(1) look at the before- image and the 4th arrow from the left on the backward edge - you can see how it's fixed in the after- image. There are many more such arrows if you look closely.

(2) Here's a real-world example: http://woahwoah.ballerterran.com/images/B_field_coil.png posted by remo - this magnetic field is missing directional arrows, hindering the image "readability."

Dave
-email is unavailable-

Dave Goel <deego>
Thu 18 Feb 2016 05:28:05 AM UTC, original submission:

Dear Octave,

The arrowhead drawing in both matlab and octave is a massive hack. In principle, of course, the arrowhead is a nice round cone. In practice, being the hack it is, it is a 2-d arrow, and has its own plane. The problem is that many times, its plane is the "into the screen" plane, which renders the arrowhead basically invisible.

If you look at this figure, http://gnufans.net/~fsbot/tmp/before.png
, you will see many arrows that are basically invisible. In fact, a user (remo on #octave) came in complaining about precisely this issue.

Now, compare the before- image with the and after- image here:
http://gnufans.net/~fsbot/tmp/after.png

The after-image guarantees that every single arrowhead will be visible.

In keeping with the hack, the only trick I employed is to use 4 arrows instead of 2 per arrowhead. You don't readily see them, but every head now has 4 arrows. That's still not a nice round cone around the head, but is much closer to the concept.

Here is the simple fix I made to _quiver_.m to accomplish this:
I replaced this code:

## if (is3d)

## h2 = plot3 ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
## [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
## [zarrw1.'; zend.'; zarrw2.'; NaN(1, length (z))](:),
## "linestyle", ls, "color", lc, "parent", hg);

by:

if (is3d)

xarrw3=xarrw1; yarrw3=yarrw2;
xarrw4=xarrw2; yarrw4=yarrw1;
nans2=NaN(1,2*length(xend));
xarrw13=[xarrw1(:); xarrw3(:)];
xarrw24=[xarrw2(:); xarrw4(:)];
yarrw13=[yarrw1(:); yarrw3(:)];
yarrw24=[yarrw2(:); yarrw4(:)];
zarrw13=[zarrw1(:); zarrw1(:)];
zarrw24=[zarrw2(:); zarrw2(:)];
xend11=[xend(:); xend(:)];
yend11=[yend(:); yend(:)];
zend11=[zend(:); zend(:)];

h2 = plot3 ( ...
[xarrw13(:), xend11(:), xarrw24(:), nans2(:)]' ,
[yarrw13(:), yend11(:), yarrw24(:), nans2(:)]' ,
[zarrw13(:), zend11(:), zarrw24(:), nans2(:)]' ,
"linestyle", ls, "color", lc, "parent", hg);

It would be wonderful if GNU Octave could incorporate this code or the equivalent =)

Many thanks,
Dave

Dave Goel <deego>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by lachlan (Posted a comment)
  • -email is unavailable- added by deego (Submitted the item)
  • -email is unavailable- added by deego (Dave Goel : improved quiver3)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

     

     

    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-02-18 deego Carbon-Copy- => Added -email is unavailable-

    Back to the top


    Powered by Savane 3.4