salut
je cherche un objet max de type convex_hull quelqu'un sait s'il existe un objet qui fait ça ?
également je cherche un objet qui pourrait me donner l'aire suivant la position de mes doigts. je m'explique : par exemple je pose 3 doigts (sur Ipad), formant un triangle, je voudrais récupérer la surface/aire. par exemple si mes doigts sont serrés aire petite, si mes doigts sont ouvert aire grande..... que ça puisse fonctionner si je pose, 3 /4/5 doigts par exemple... j'ai essayé de faire ça avec un vexpr mais le résultat est bien médiocre.... il faut que je révise mes cours de géométrie.
connaissez vous un objet qui pourrai faire cela ?
thanks
O-O
Hors ligne
Ce code appartient à Ali Momeni, il fonctionnait sous Max 4. Je ne peux pas certifier qu'il fonctionne sous Max 5, mais il faut essayer. Il y a 2 fichiers Javascript et 1 patch.
Sinon il y a un convex hull sous Pd.
/////////////////ali.convex-hull.js/////////////////////
var allBaseLines = new Array();
function buildConvexHull(baseLine, points) {
allBaseLines.push(baseLine)
var convexHullBaseLines = new Array();
var t = findMostDistantPointFromBaseLine(baseLine, points);
if (t.maxPoint.length) { // if there is still a point "outside" the base line
convexHullBaseLines =
convexHullBaseLines.concat(
buildConvexHull( [baseLine[0],t.maxPoint], t.newPoints)
);
convexHullBaseLines =
convexHullBaseLines.concat(
buildConvexHull( [t.maxPoint,baseLine[1]], t.newPoints)
);
return convexHullBaseLines;
} else { // if there is no more point "outside" the base line, the current base line is part of the convex hull
return [baseLine];
}
}
function getConvexHull(points) {
//find first baseline
var maxX, minX;
var maxPt, minPt;
for (var idx in points) {
var pt = points[idx];
if (pt[0] > maxX || !maxX) {
maxPt = pt;
maxX = pt[0];
}
if (pt[0] < minX || !minX) {
minPt = pt;
minX = pt[0];
}
}
var ch = [].concat(buildConvexHull([minPt, maxPt], points),
buildConvexHull([maxPt, minPt], points))
return ch;
}
////////////////////////////ali.xy-ui.js////////////////////////
inlets = 2;
outlets = 2;
sketch.default2d();
//sketch.gldisable("depth_test");
sketch.glclearcolor(0.,0.,0,1.);
sketch.glclear();
// sketch prefs
sketch.fontsize(9);
// global varables and code
var points = new Array();
//var POINTSIZE = jsarguments[1];
var DRAWBALLS = 1;
var BALLSIZE = 0.051;
var VISUALS = 1;
var VSLICES = 12;
var OUTPUTAMBI = 0;
var RANGE = new Array(4);
RANGE[0] = -1;
RANGE[1] = 1;
RANGE[2] = -1;
RANGE[3] = 1;
//init();
var modclick = 0;
init.local = 1;
function init()
{
sketch.default3d();
//sketch.gldisable("depth_test");
sketch.glclearcolor(0.,0.,0,1.);
sketch.glclear();
}
//----------------for cleanup --------------------
function list()
{
v = arrayfromargs(arguments);
if (inlet = 1)
{
for (var k=0; k<v.length/2;k++)
{
(k,v[k*2],v[k*2+1]);
}
}
}
function clear()
{
points=new Array();
grid=new Array();
pointsnum = 0;
sketch.glclear();
refresh();
}
function redraw()
{
sketch.glclear();
drawlabels();
refresh();
}
//-----------msg's from outside
function set(n,x,y)
{
//place(n,scale(x,RANGE[0],RANGE[1],-1, 1),scale(y,RANGE[2],RANGE[3],-1, 1));
place(n,x,y);
redraw();
//outputpos(n);
}
function setnoout(n,x,y)
{
place(n,x,y);
redraw();
}
function setall()
{
v = arrayfromargs(arguments)
var k = 0;
for(k=0;k<v.length/2;k++)
{
place(k,v[2*k],v[2*k+1]);
outputpos(k);
}
redraw();
}
function setx(n,x)
{
place(n,x,points[n][1]);
redraw();
outputpos(n);
}
function sety(n,y)
{
place(n,points[n][0],y);
redraw();
outputpos(n);
}
function add(n,x,y)
{
addpoint(n+1,x,y);
redraw();
}
function setsize(r)
{
BALLSIZE = r;
redraw();
}
function setvisuals(n)
{
VISUALS = n;
if (n > 0) { redraw(); } else {sketch.glclear(); refresh();}
}
function setdrawballs(n)
{
DRAWBALLS = n;
}
function setrange(xmin,xmax,ymin,ymax)
{
RANGE[0] = xmin;
RANGE[1] = xmax;
RANGE[2] = ymin;
RANGE[3] = ymax;
}
//---------------color grid related ---------------
drawlabels.local = 1;
function drawlabels()
{
// post("drawing: ",n,"\n");
if (VISUALS > 0)
{
with (sketch) {
shapeslice(VSLICES);
for (j=0; j < points.length ; j++) {
//post("drawing: index ", j, "\n");
//post("drawing: x ", points[j][0],"\n");
//post("drawing: y ", points[j][1],"\n");
moveto(points[j][0],points[j][1]);
if (DRAWBALLS==1) {
glcolor(.5,0.,0.);
//sphere(BALLSIZE);
circle(BALLSIZE);
}
glcolor(1.,1.,1.);
moveto(points[j][0]-0.02,points[j][1]-0.02);
jString = j; //added one to match pattr's preset numbering.
jString = jString + "";
text(jString);
refresh();
}
}
}
}
function test()
{
// post("drawing: ",n,"\n");
with (sketch) {
shapeslice(VSLICES);
for (j=0; j < points.length ; j++) {
post("test drawing: ", j, points[j][0],points[j][1],"\n");
moveto(points[n][0],points[n][1]);
glcolor(.5,0.,0.);
sphere(BALLSIZE);
}
}
refresh();
}
drawSphere.local = 1;
function drawSphere(x,y,rad,R,G,B)
{
with (sketch)
{
shapeslice(VSLICES);
moveto(x,y,0);
glcolor(R,G,B);
sphere(rad);
refresh();
}
}
// this is a special method, made for one the fly space making with no visuals
// note that this doesn't fill up the grid.
newpoint.local = 1;
function newpoint()
{
var v = arrayfromargs(arguments);
n=points.length;
points[n]=new Array ();
for (j=0; j < v.length; j++) {
points[n][j]=v[j];
}
outlet(1,"newpoint", n);
notifyclients();
//redraw();
//params=params.concat(v);
//for (j=0; j < params.length; j++) {
// post("here's param: ", params[j], "\n");
//}
//addpoint(params);
}
addpoint.local = 1;
function addpoint()
{
// arguments:
// note: in the points array the indeces are one less than what is below
// because the point number is not stored in the points array.
// it's implicity cuz it's the index in the points array itself.
// 0: point #
// 1: x center position
// 2: y center position
// 3: z center height (optional)
// 4: x variance (optional)
// 5: y variance (optional)
// 6: R (optional)
// 7: G (optional)
// 8: B (optional)
var v = arrayfromargs(arguments);
//post("hi");
//for (j=0; j < v.length; j++) {
// post("here's param: ", v[j], "\n");
//}
n=v[0]-1; //subtracting one to match pattr's numbering system
points[n]=new Array();
//post("adding: ", v, "\n");
// for the provided arguments do, put them in the points array:
for (j=1; j < v.length; j++) {
points[n][j-1]=v[j];
}
/*
// for the rest, set initial values:
for (j=v.length; j < 9; j++) {
switch (j) {
case 3: points[n][2]= 1.; //default center height
case 4: points[n][3]= .14; // 4: x variance (optional)
case 5: points[n][4]= .14; // 5: y variance (optional)
case 6: points[n][5]= 1.; // 7: R (optional)
case 7: points[n][6]= 0.; // 8: G (optional)
case 8: points[n][7]= 0.; // 9: B (optional)
}
}*/
// make grid for this point
notifyclients();
}
function deletepoint(n)
{
}
//-------------------------interaction-----------------
onclick.local = 1;
function onclick (x,y,but,mod1,shift,caps,opt,mod2)
{
if (opt+mod1+shift>0) {
modclick =1;
// post("prevgridsize=gridsize;");
// prevgridsize=gridsize;
// gridsize=smallgrid;
// fillgrid()
}
modx=sketch.screentoworld(x,y)[0];
mody=sketch.screentoworld(x,y)[1];
closest= closestpoint(modx,mody);
// optclick=opt;
// shiftclick=shift;
// ctlclick=mod2;
}
ondblclick.local = 1;
function ondblclick(x,y,but,mod1,shift,caps,opt,mod2)
{
cx=sketch.screentoworld(x,y)[0];
cy=sketch.screentoworld(x,y)[1];
if (shift == 0) {
// post("adding number: ", points.length);
addpoint(points.length+1,cx,cy); //the plus 1 is to adjust for addpoint()'s adjustment for pattr's numbering
// post("now we have: ", points.length);
redraw();
closest= closestpoint(cx,cy);
}
if (shift == 1) {
deletepoint(closestpoint(cx,cy)+1);
redraw();
}
}
place.local = 1;
function place()
{
points[arguments[0]][0] = arguments[1];
points[arguments[0]][1] = arguments[2];
notifyclients();
}
outputpos.local = 1;
function outputpos(n)
{
//var x = scale(points[n][0],-1,1,RANGE[0],RANGE[1]);
var x = points[n][0];
//var y = scale(points[n][1],-1,1,RANGE[2],RANGE[3]);
var y = points[n][1];
outlet(0,"pos",[n,x,y]);
if (OUTPUTAMBI) {
ambisonicoutput(n,x,y);
}
}
ambisonicoutput.local = 1;
function ambisonicoutput(n,x,y)
{
var r = Math.sqrt(x*x+y*y)*10;
var theta = 0;
if (x>=0)
{
if (y >= 0)
{
//top right
theta = Math.atan(x/y);
}
if (y < 0)
{
//bottom right
theta = Math.PI+Math.atan(x/y);
}
}
if (x<0)
{
if (y >= 0)
{
//top left
theta = Math.atan(x/y);
}
if (y < 0)
{
//bottom left
theta = -Math.PI + Math.atan(x/y);
}
}
outlet(0,"ambisonic", ["aed", n+1,theta/Math.PI*180, 0, r, 1]);
}
ondrag.local = 1;
function ondrag (x,y,but,mod1,shift,caps,opt,mod2)
{
if (shift + opt + mod1 + mod2 == 0) {
//lookup(sketch.screentoworld(x,y)[0], sketch.screentoworld(x,y)[1]);
}
if (shift == 0) {
if (but == 1) { //still dragging
sketch.glclear();
cx=sketch.screentoworld(x,y)[0];
cy=sketch.screentoworld(x,y)[1];
// post("checking ", cx, " ", cy, "\n");
// post("calling placeone with: ", closestpoint(cx,cy),cx,cy,"/n");
place(closest, cx, cy);
outputpos(closest);
drawlabels();
refresh();
}
if (but == 0) { //stopped traggng
//draw();
// post("does this happen?");
shiftclick=ctlclick=optclick=modclick=0;
cx=sketch.screentoworld(x,y)[0];
cy=sketch.screentoworld(x,y)[1];
closest= closestpoint(cx,cy);
}
}
if (but == 1 && modclick==1) {
//modclick = 2;
}
if (but == 0 && modclick == 2) {
/*modclick = 0;
// post("setting gridsize from: ",gridsize,"to: ",prevgridsize);
// gridsize = prevgridsize;
shiftclick=ctlclick=optclick=modclick=0;
fillgrid();
redraw();*/
}
if (opt == 1) { //change sigma x and sigma y
/*cx=sketch.screentoworld(x,y)[0];
cy=sketch.screentoworld(x,y)[1];
// post("modx: ",modx," mody: ",cy," mody: ",cx," cy: ",cy,"closest: ",closest)
sx_new = points[closest][3]+scale(cx-modx,-1.,1., -.42, .42);
sy_new = points[closest][4]+scale(cy-mody,-1.,1., -.42, .42);
// don’t allow negative sigmas
if (sx_new > 0) {
points[closest][3]=sx_new;
}
if (sy_new > 0) {
points[closest][4]=sy_new;
}
// visual feedback
drawquadframe(closest);
modx=cx;
mody=cy;
refresh();
notifyclients();
// fillgrid(closest)
// redraw();
if (but == 0) { //stopped traggng
postondrag;
} */
}
if (mod1 == 1) { //command drag, to change height
/*
//cx=sketch.screentoworld(x,y)[0];
cy=sketch.screentoworld(x,y)[1];
z_new = points[closest][2]+scale(cy-mody,-1.,1., -.35, .35);
if (z_new > 0) {
points[closest][2]=z_new; }
drawquadframe(closest);
notifyclients();
mody=cy;
// fillgrid(closest)
// redraw();
if (but == 0) { //stopped traggng
postondrag;
}
*/
}
}
postondrag.local = 1;
function postondrag()
{ //stopped traggng
modclick = 0;
// post("setting gridsize from: ",gridsize,"to: ",prevgridsize);
// gridsize = prevgridsize;
shiftclick=ctlclick=optclick=modclick=0;
// fillgrid();
// redraw();
}
onresize.local = 1;
function onresize()
{
init();
}
//---------------------calculations.----------------
getdistances.local = 1;
function getdistances()
{
var distances = new Array(points.length);
// post("looking up ", arguments[0][0],"\n")
for (j=0; j < points.length ; j++) {
distances[j]=Math.sqrt((points[j][0]-arguments[0])*(points[j][0]-arguments[0])+(points[j][1]-arguments[1])*(points[j][1]-arguments[1]));
}
return(distances);
}
// -------------------------------math helpers-------
scale.local = 1;
function scale(x,inmin, inmax,outmin,outmax)
{
var xout = (x-inmin)/(inmax-inmin)*(outmax-outmin)+outmin;
// post("here's the scaled: ", xout, "\n");
return xout;
}
gaussian.local = 1;
function gaussian(x,y,cx,cy,cz,sigx,sigy)
{
var g=cz*1/2/Math.PI/sigx/sigy*Math.exp(-1*((x-cx)*(x-cx)/2/sigx/sigx+(y-cy)*(y-cy)/2/sigy/sigy));
return g;
}
maxElement.local = 1;
function maxElement(v)
{
var max = v[0];
//post("here's initial max: ", max, "\n");
for (i = 1; i < v.length; i++) {
max = (max < v[i])?v[i]:max; // if (max < v[i]) max = v[i];
}
return max;
}
function minElement(v)
{
var min = v[0];
for (i = 1; i < v.length; i++) {
min = (min > v[i])?v[i]:min; // if (min > v[i]) min = v[i];
}
return min;
}
closestpoint.local = 1;
function closestpoint(cx, cy)
{
var mindist = 99999999;
var minid = 0;
var distlist = getdistances(cx,cy);
for (j=0; j < distlist.length; j++) {
if (distlist[j] < mindist ) {
// post("distance from ", j, " ---> ", distlist[j], " \n");
minid = j;
mindist = distlist[j];
}
}
return(minid);
}
function dump()
{
for (j=0; j < points.length; j++) {
outlet(1,"dump",j+1, points[j]);
}
outlet(1,"dump","done");
}
// -------------------for debugging--------------
function print()
{
var v = arrayfromargs(arguments);
post("--------\n","there are currnetly this many points: ",points.length,"\n");
if (v.length>0) {
for (j=0; j < v.length; j++) {
post("point number: ", j+1, "--- value: ", points[v[j]],"\n");
}
}
else {
for (j=0; j < points.length; j++) {
post("point number: ", j+1, "--- value: ", points[j],"\n");
}
}
}
function postarray(array)
{
for (j=0; j < array.length; j++) {
post("here's array element ",j, " : ", array[j], "\n");
}
}
// ------------------------------for pattr----------------------
function setvalueof()
{
var frompattr=arrayfromargs(arguments);
// post("frompattr has this many items:", frompattr.length,"\n");
// post("frompattr is : ",frompattr,"\n");
n=frompattr.length/2;
// post("from pattr has this many points:", n, "\n");
points=new Array();
for (kk=0;kk< n;kk++)
{
//makegrid(kk);
points[kk]=new Array();
// post("setting point number ", kk, " to value ",frompattr.slice(0,8),"\n");
points[kk]=frompattr.slice(0,2);
frompattr = frompattr.slice(2);
}
// post("number of points is now: ", points.length, "\n");
//fillgrid();
redraw();
}
function getvalueof()
{
var topattr = new Array();
for (j=0;j<points.length; j++) {
topattr = topattr.concat(points[j]);
}
return topattr;
}
/////////////////////////////////////////////////////
Max Patch
<pre><code>
----------begin_max5_patcher----------
997.3ocyZssaiBCD84juBDOmF46FuuseGqVshDbSbDwf3xtosp+6K1lzPaSA
ZSwIRsbwXvyblyb7X29z7YgqxNHKCC9QvuBlM6o4ylYaxzvr16mEtO9v5z3R
a2B0x+ksZW3B2ipjGprM+XZfpRVDfN9j73p0aU5M+oPttxM.H.bIXQ.FfMmH
ByQDXIH32suitdeVcUprxNTn1VuOSWUpdTZZChZdIWytdV8Ptz80CCWz76Ke
KUh0tZr06v7vNeJc7d6aD9yBUbZ3ogVoeYjMs8774lCKtLbIuPoq5AS3bKjv
n1SjAfDP+PRWel8I8Y3WvmWUWUko6w6vDly8PGcrdcO3GEZWEq2b9PKwiNCx
FjXSkq.+1bkuHWD6RIoT12MYD3AxnwMkIpp2412AVxXBj.F.VRE.JEFXZxzB
1bEjQwTRyCIQQvHgoIJhSohllXHg.YdQBhBE7Nc27Ihn.roW.TCCG0bAGiPQ
3iVPpRKWmUqslAqGbW3zEirvODwd4zGf7jufxnMz+VQx6K1rx0GvRzhNGfcF
6NARj3VPUAwb7TW93DjJh3SepnLWpSBVmo+q7v15zzd7WH24u.qJJDRGoCOZ
5wYw.pGB0ebwDExM8w.hHNkJWkD.eUIAhb8pjnnwLkA1a6QJAPcoFVFCC5Mf
AcUYKkop0x.XO.CiScTEa8VTt2.FnGXLCpXxHHm2KlHESH2CQ4MMo.4ivKoN
wAruhwP50VUHISKGFXvQ1SrHuALXOnJrWVVFuQ9NjIodeejELyoD3nLVgRXz
zNkJD4AdxGAGqy1mqR6ikzT96o59c3xjiHfqdlS+rjiYNNwDt2lOUbESbFZY
hDW8VNdh63TySh7.MYWYspOu1UYkqvSjaIxHyLMCPEFHluqLtXS8dotpcW3N
s1rlr0Wb03T0xCObWsZ4txv2iOL+jrLpUqztiVPKBI71bMzqXFyvZqNoUHC3
OsUxUcxliDk.vRyOviGgsW26xcca.RjkHA4dQgAe8lHZWYfI8NOK8gMY561J
SykEcxyOGDQc6APq5KR3icD.dAYX1umcCwdyerAqyYZ+03VYVcw5iVSa7I3j
2kHKqT53JUypdN0G3q5yVURhT2ciJ2qRxyTcTZOaLbrVD4lyhLUSMnIw7pIE
cyYQlhvuwLIynAGvhD9Ej3igbS8pMIFiIg8KLMJUIt+sogXSH+JLYGN3sEcB
MFc.y981wvmbaZLyof7LNwGKN4Qahd6M26XLIzmTEmHbqkhaqr6xfrwHe9lb
hoFyvvwDFQ2dy7g+jzcBs8euC1EGGwjIfm4EaxySCNBSxuBoiQf.yt4.I7kD
2Zt444+GeY+u9A
-----------end_max5_patcher-----------
</code></pre>
Hors ligne
Bonjour,
Tu peux calculer l'aire d'un triangle quelconque si tu connais les coordonnées des 3 points avec cette formule :
0.5 * abs ( ((xb - xa)*(yc - ya)) - ((xc - xa) * (yb - ya)) )
c'est à dire la moitié de la valeur absolue de ...
(d'après http://fr.wikipedia.org/wiki/Aire_d%27un_triangle )
Avec plus de points, il faut surement commencer par faire une triangulation de la surface et calculer la somme des surfaces, mais je n'ai rien à te proposer...
Hors ligne
Pages: 1