turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Close

.NET

- Autodesk Community
- >
- AutoCAD Customization
- >
- .NET
- >
- Re: Projection by a vector to a plane

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page

Active Contributor

35 Posts

0 Kudos

Registered:
05-23-2012

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

690 Views, 10 Replies

05-06-2013 03:37 AM

Hi guys! This days I was troubled by a problem.

First of all, I find a function in the netapi:

Public Shared Function Projection(projectionPlane As Autodesk.AutoCAD.Geometry.Plane, projectDir As Autodesk.AutoCAD.Geometry.Vector3d) As Autodesk.AutoCAD.Geometry.Matrix3d

Autodesk.AutoCAD.Geometry.Matrix3d 的成员

Now ,I just want to figure out this Matrix3d by the vector and plane known! Because I can't use this function In other software like Rhino. Can you help me to get this transform?Thank you very much!

Solved! Go to Solution.

Solved! by _gile. See the answer in context.

Hi,

Inspired by this (old) LISP routine from my library (AutoLISP does not provide functions to deal with vectors and matrices),

;; Multiply a vector by a scalar (defun vxs (v s) (mapcar (function (lambda (x) (* x s))) v) ) ;; Return the dot product of two vectors (defun vxv (v1 v2) (apply '+ (mapcar '* v1 v2)) ) ;; Apply a transformation matrix to a vector -Vladimir Nesterovsky- (defun mxv (m v) (mapcar (function (lambda (r) (vxv r v))) m) ) ;; Return the transformation matrix (4x4) describing the projection ;; to the plane defined by its origin and normal along the direction vector (defun projMat (org norm dir / mat) (append (mapcar (function (lambda (v x) (append v (list x)))) (setq mat (mapcar (function (lambda (v1 v2) (mapcar '- v1 v2))) '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.)) (mapcar (function (lambda (x) (vxs norm x))) (vxs dir (/ 1. (vxv norm dir))) ) ) ) (mapcar '- org (mxv mat org)) ) '((0. 0. 0. 1.)) ) )

here's a C# adaptation. It returns the same matrix as the built-in Matrix3d.Projection() method.

I overloaded the method so that it's possible to pass a Plane instance or a Point3d (origin) and a Vector3d (normal) as arguments.

public Matrix3d ProjectionMatrix(Plane projectionPlane, Vector3d projectDir) { return ProjectionMatrix(projectionPlane.PointOnPlane, projectionPlane.Normal, projectDir); }

public Matrix3d ProjectionMatrix(Point3d origin, Vector3d normal, Vector3d projectDir) { double scale = normal.DotProduct(projectDir); Vector3d dir = projectDir / scale; Vector3d xVec = Vector3d.XAxis - normal * dir.X; Vector3d yVec = Vector3d.YAxis - normal * dir.Y; Vector3d zVec = Vector3d.ZAxis - normal * dir.Z; Vector3d orgVec = origin.GetAsVector(); return new Matrix3d(new double[16] { xVec.X, xVec.Y, xVec.Z, origin.X - xVec.DotProduct(orgVec), yVec.X, yVec.Y, yVec.Z, origin.Y - yVec.DotProduct(orgVec), zVec.X, zVec.Y, zVec.Z, origin.Z - zVec.DotProduct(orgVec), 0.0, 0.0, 0.0, 1.0 }); }

ADN Support Specialist

685 Posts

80 Kudos

Registered:
06-02-2009

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-09-2013 07:59 AM in reply to:
huaxiamengqing

Hi

That's a pure algorithmic question, nothing here related to Autodesk APIs. The source code of this method is not public, you should be able to find detailed elements of answer from mathematical resources on the web looking for projection matrices, unless somebody on this forum has custom code to share with you:

http://en.wikipedia.org/wiki/Projection_%28linear_

I hope it helps.

Regards,

Philippe.

Developer Technical Services

Autodesk Developer Network

Active Contributor

35 Posts

0 Kudos

Registered:
05-23-2012

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-09-2013 08:15 AM in reply to:
philippe.leefsma

Yes, you are right. But the url is useless,I have read it before.I have read many math resource.But I can get the right Matrix.

In rhino Grassshoper forum they can not solve this problem, They say this forum May have some upperhand can make it. I think they are wrong.

So few people Know this.

Tell me does code need math??

Yes, absolutly yes. if you didn't do best in math, You will always need to find apis,If there is not a api you need,You are OVER!

Valued Contributor

59 Posts

5 Kudos

Registered:
12-08-2010

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2013 06:03 AM in reply to:
huaxiamengqing

I am not sure if you need this but below I quickly put alogorithm for finding perpendicular projection from point on plane.

But if you need projection by any vector it is just finding intersection between line and plane ( that is not so hard to calculate)

To find perp. projection on plane can be calculated like this (it is not code just algorithm)

1) calculate normal of plane by 3 points A B C

for(i=0;i<3;i++)

{

v1[i] = c[i]-b[i];

v2[i] = a[i]-b[i];

}

vnorm[0]=v1[1]*v2[2]-v1[2]*v2[1];

vnorm[1]=v1[2]*v2[0]-v1[0]*v2[2];

vnorm[2]=v1[0]*v2[1]-v1[1]*v2[0];

it must have size 1 therefore

rdist=vnorm[1-1]*vnorm[1-1]+vnorm[2-1]*vnorm[2-1]+vnorm[3-1]*vnorm[3-1];

rdist=sqrt(rdist);

vnorm[0]=vnorm[0]/rdist;

vnorm[1]=vnorm[1]/rdist;

vnorm[2]=vnorm[2]/rdist;

2) perpendicular projection of point on plane

double product=0;

for (i=0;i<3;i++)

product+=(a[i]-d[i])*vorm[i];

for (i=0;i<3;i++)

pktproj[i]=d[i]+product*vnorm[i]

Richard

Active Contributor

35 Posts

0 Kudos

Registered:
05-23-2012

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2013 06:14 AM in reply to:
huaxiamengqing

Thank you.But you code is to simple. That matrix is easy for me.All the projection of point or projection by plane.x,y,z has figured.

but Projection by a vector to a plane ,if the vector is Arbitrary is hard to figure out!

Whatever,Thank you for your answer!

*Expert Elite*

2,140 Posts

253 Kudos

Registered:
04-29-2006

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2013 01:59 PM in reply to:
huaxiamengqing

Hi,

Inspired by this (old) LISP routine from my library (AutoLISP does not provide functions to deal with vectors and matrices),

;; Multiply a vector by a scalar (defun vxs (v s) (mapcar (function (lambda (x) (* x s))) v) ) ;; Return the dot product of two vectors (defun vxv (v1 v2) (apply '+ (mapcar '* v1 v2)) ) ;; Apply a transformation matrix to a vector -Vladimir Nesterovsky- (defun mxv (m v) (mapcar (function (lambda (r) (vxv r v))) m) ) ;; Return the transformation matrix (4x4) describing the projection ;; to the plane defined by its origin and normal along the direction vector (defun projMat (org norm dir / mat) (append (mapcar (function (lambda (v x) (append v (list x)))) (setq mat (mapcar (function (lambda (v1 v2) (mapcar '- v1 v2))) '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.)) (mapcar (function (lambda (x) (vxs norm x))) (vxs dir (/ 1. (vxv norm dir))) ) ) ) (mapcar '- org (mxv mat org)) ) '((0. 0. 0. 1.)) ) )

here's a C# adaptation. It returns the same matrix as the built-in Matrix3d.Projection() method.

I overloaded the method so that it's possible to pass a Plane instance or a Point3d (origin) and a Vector3d (normal) as arguments.

public Matrix3d ProjectionMatrix(Plane projectionPlane, Vector3d projectDir) { return ProjectionMatrix(projectionPlane.PointOnPlane, projectionPlane.Normal, projectDir); }

public Matrix3d ProjectionMatrix(Point3d origin, Vector3d normal, Vector3d projectDir) { double scale = normal.DotProduct(projectDir); Vector3d dir = projectDir / scale; Vector3d xVec = Vector3d.XAxis - normal * dir.X; Vector3d yVec = Vector3d.YAxis - normal * dir.Y; Vector3d zVec = Vector3d.ZAxis - normal * dir.Z; Vector3d orgVec = origin.GetAsVector(); return new Matrix3d(new double[16] { xVec.X, xVec.Y, xVec.Z, origin.X - xVec.DotProduct(orgVec), yVec.X, yVec.Y, yVec.Z, origin.Y - yVec.DotProduct(orgVec), zVec.X, zVec.Y, zVec.Z, origin.Z - zVec.DotProduct(orgVec), 0.0, 0.0, 0.0, 1.0 }); }

Gilles Chanteau

Valued Mentor

370 Posts

175 Kudos

Registered:
05-06-2012

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-10-2013 11:53 PM in reply to:
huaxiamengqing

Perhaps this will help (no dependence on any commercial software and completely open source without restriction):

The OpenNurbs Initiative: http://www.opennurbs.org/

.NET managed wrappers for OpenNurbs: https://github.com/mcneel/rhinocommon

*Expert Elite*

2,140 Posts

253 Kudos

Registered:
04-29-2006

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-11-2013 01:06 AM in reply to:
_gile

Here's a (may be) more explainatory version (decomposed and commented).

public Matrix3d ProjectionMatrix(Point3d origin, Vector3d normal, Vector3d projectDir) { // Calculate a scale factor // If scale = 0 (normal is perpendicular to projectDir) this won't throw // an exception but return an unusable matrix : // ((NaN,NaN,-Infinity,NaN),(NaN,NaN,NaN,NaN),(NaN,NaN,NaN,NaN),(0,0,0,1)) double scale = normal.DotProduct(projectDir); // apply the scale factor to projectDir Vector3d dir = projectDir / scale; // Build the row vectors of the 'linear part' of the matrix (3x3 matrix) Vector3d xVec = Vector3d.XAxis - normal * dir.X; Vector3d yVec = Vector3d.YAxis - normal * dir.Y; Vector3d zVec = Vector3d.ZAxis - normal * dir.Z; // Build the 'translational part' of the matrix (column vector) Vector3d orgVec = origin.GetAsVector(); // Apply the 'linear part' matrix to the origin Point3d transformedOrigin = new Point3d( xVec.DotProduct(orgVec), yVec.DotProduct(orgVec), zVec.DotProduct(orgVec)); // The displacement vector is the vector from tranformedOrigin to origin Vector3d disp = origin - transformedOrigin; // Assemble the 4x4 transformation matrix return new Matrix3d(new double[16] { xVec.X, xVec.Y, xVec.Z, disp.X, yVec.X, yVec.Y, yVec.Z, disp.Y, zVec.X, zVec.Y, zVec.Z, disp.Z, 0.0, 0.0, 0.0, 1.0 }); }

Gilles Chanteau

Valued Mentor

370 Posts

175 Kudos

Registered:
05-06-2012

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-12-2013 12:15 AM in reply to:
_gile

Hi Gile.

My interpretation of the OP's post is that he can't have any dependenc on any AutoCAD APIs.

*Expert Elite*

2,140 Posts

253 Kudos

Registered:
04-29-2006

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-12-2013 01:01 AM in reply to:
DiningPhilosopher

Hi Tony,

This is what I understood too.

The reasons why I posted some code are the ability to test in AutoCAD if the returned matrix is the same as the one returned by Matrix3d.Projection(), and the fact it's easier for me to post some commented code than to try an explanation in English.

I hope the OP would be able to adapt it with the corresponding types to Point3d, Vector3d and the DotProduct() method.

Gilles Chanteau

Search This Board

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Post to the Community

Have questions about Autodesk products? Ask the community.

The Knowledge Network

Access a broad range of knowledge to help get the most out of your products and services.

Download & Installation

Getting your Software

Downloads & Upgrades

Serial Numbers & Product Keys

Installation & Licensing

Activation & Registration

Network License Administration

Subscription Management

Sign In / Create Account

Maintenance Subscription Help

Desktop Subscription Help

Cloud Service Subscription FAQ

- Privacy | Legal Notices & Trademarks | Report Noncompliance | Site map | © Copyright 2014 Autodesk Inc. All rights reserved

Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. Please see the Autodesk Creative Commons FAQ for more information.