Chipmunk Geometric algorithm

Source: Internet
Author: User

/* Copyright (c) Scott Lembcke
*
* Permission is hereby granted, free of charge, to all person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* In the software without restriction, including without limitation the rights
* To use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* Copies of the software, and to permit persons to whom the software are
* Furnished to does so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall is included in
* All copies or substantial portions of the software.
*
* The software is provided ' as is ', without WARRANTY of any KIND, EXPRESS OR
* implied, including but not LIMITED to the warranties of merchantability,
* FITNESS for A particular PURPOSE and noninfringement. In NO EVENT shall the
* AUTHORS or COPYRIGHT holders be liable for any CLAIM, damages or other
* Liability, WHETHER in a ACTION of contract, TORT OR OTHERWISE, arising from,
* Out of OR in CONNECTION with the software or the use or other dealings in the
* Software.
*/

#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "chipmunk_private.h"

void
Cpmessage (const char *condition, const char *file, int line, Cpbool isError, Cpbool isharderror, const char *message, ...)
{
fprintf (stderr, IsError? "Aborting due to Chipmunk error:": "Chipmunk Warning:"));

Va_list Vargs;
Va_start (vargs, message); {
vfprintf (stderr, message, Vargs);
fprintf (stderr, "\ n");
} va_end (Vargs);

fprintf (stderr, "\tfailed condition:%s\n", condition);
fprintf (stderr, "\tsource:%s:%d\n", file, line);

if (IsError) abort ();
}

#define STR (s) #s
#define XSTR (s) STR (s)

const char *cpversionstring = XSTR (cp_version_major) "." XSTR (Cp_version_minor) "." XSTR (cp_version_release);

void
Cpinitchipmunk (void)
{
Cpassertwarn (Cpfalse, "cpinitchipmunk is deprecated and no longer required. It'll be removed on the future. ");
}

Mark:misc Functions

Cpfloat
Cpmomentforcircle (cpfloat m, cpfloat R1, cpfloat R2, cpvect offset)
{
Return m* (0.5f* (r1*r1 + r2*r2) + cpvlengthsq (offset));
}

Cpfloat
Cpareaforcircle (cpfloat R1, cpfloat R2)
{
Return (cpfloat) m_pi*cpfabs (R1*R1-R2*R2);
}

Cpfloat
Cpmomentforsegment (cpfloat m, cpvect A, cpvect b)
{
Cpvect offset = Cpvmult (Cpvadd (A, B), 0.5f);
Return m* (CPVDISTSQ (b, a)/12.0f + cpvlengthsq (offset));
}

Cpfloat
Cpareaforsegment (Cpvect A, Cpvect B, Cpfloat R)
{
Return r* ((cpfloat) M_pi*r + 2.0f*cpvdist (A, b));
}

Cpfloat
Cpmomentforpoly (cpfloat m, const int numverts, const cpvect *verts, cpvect offset)
{
Cpfloat sum1 = 0.0f;
Cpfloat sum2 = 0.0f;
for (int i=0; i<numverts; i++) {
Cpvect v1 = Cpvadd (verts[i], offset);
Cpvect v2 = Cpvadd (verts[(i+1)%numverts], offset);

Cpfloat a = Cpvcross (v2, v1);
Cpfloat B = Cpvdot (v1, v1) + Cpvdot (v1, v2) + Cpvdot (v2, v2);

Sum1 + = A*b;
Sum2 + = A;
}

Return (M*SUM1)/(6.0F*SUM2);
}

Cpfloat
Cpareaforpoly (const int numverts, const cpvect *verts)
{
Cpfloat area = 0.0f;
for (int i=0; i<numverts; i++) {
Area + = Cpvcross (Verts[i], verts[(i+1)%numverts]);
}

return-area/2.0f;
}

Cpvect
Cpcentroidforpoly (const int numverts, const cpvect *verts)
{
Cpfloat sum = 0.0f;
Cpvect vsum = Cpvzero;

for (int i=0; i<numverts; i++) {
Cpvect v1 = verts[i];
Cpvect v2 = verts[(i+1)%numverts];
Cpfloat cross = Cpvcross (v1, v2);

sum + = Cross;
Vsum = Cpvadd (Vsum, Cpvmult (Cpvadd (v1, v2), cross));
}

Return Cpvmult (Vsum, 1.0f/(3.0f*sum));
}

void
Cprecenterpoly (const int numverts, Cpvect *verts) {
Cpvect centroid = Cpcentroidforpoly (Numverts, Verts);

for (int i=0; i<numverts; i++) {
Verts[i] = Cpvsub (Verts[i], centroid);
}
}

Cpfloat
Cpmomentforbox (cpfloat m, cpfloat width, cpfloat height)
{
Return m* (Width*width + height*height)/12.0f;
}

Cpfloat
CpMomentForBox2 (cpfloat m, CPBB Box)
{
Cpfloat width = box.r-box.l;
Cpfloat height = box.t-box.b;
Cpvect offset = Cpvmult (CPV (box.l + BOX.R, box.b + box.t), 0.5f);

TODO NaN when offset is 0 and M are INFINITY
Return Cpmomentforbox (m, width, height) + m*cpvlengthsq (offset);
}

Mark:quick Hull

void
Cploopindexes (cpvect *verts, int count, int *start, int *end)
{
(*start) = (*end) = 0;
Cpvect min = verts[0];
Cpvect max = min;

for (int i=1; i<count; i++) {
Cpvect v = verts[i];

if (v.x < min.x | | (v.x = = min.x && v.y < MIN.Y)) {
min = v;
(*start) = i;
} else if (v.x > max.x | | (v.x = = max.x && v.y > Max.y)) {
max = V;
(*end) = i;
}
}
}

#define SWAP (__a__, __b__) {cpvect __tmp__ = __a__; __a__ = __b__; __b__ = __tmp__;}

Static int
Qhullpartition (cpvect *verts, int count, cpvect A, cpvect B, cpfloat tol)
{
if (count = = 0) return 0 ;

Cpfloat max = 0;
int pivot = 0;

Cpvect delta = cpvsub (b, a);
Cpfloat valuetol = tol*cpvlength (delta);

int head = 0;
for (int tail = count-1; head <= tail;) {
Cpfloat value = Cpvcross (Delta, Cpvsub (Verts[head], a));
if (value > Valuetol) {
if (value > Max) {
Max = value;
Pivot = head;
}

head++;
} else {
SWAP (Verts[head], verts[tail]);
tail--;
}
}

//Move the new pivot to the front if it's not already there.
if (pivot! = 0) SWAP (verts[0], Verts[pivot]);
return head;
}

static int
Qhullreduce (cpfloat tol, cpvect *verts, int count, cpvect A, cpvect pivot, Cpvect B, Cpvect *result)
{
if (Count < 0) {
return 0;
} else if (count = = 0) {
RESULT[0] = pivot;
return 1;
} else {
int left_count = Qhullpartition (Verts, Count, a, pivot, tol);
int index = Qhullreduce (tol, Verts + 1, left_count-1, A, verts[0], pivot, result);

result[index++] = pivot;

int right_count = qhullpartition (verts + left_count, Count-left_count, pivot, B, tol);
return index + qhullreduce (tol, verts + Left_count + 1, right_count-1, Pivot, Verts[left_count], B, result + index);
}
}

Quickhull seemed like a neat algorithm, and efficient-ish for large input sets.
My implementation performs an on place reduction using the result array as scratch space.
Int
Cpconvexhull (int count, Cpvect *verts, cpvect *result, int *first, cpfloat tol)
{
if (result) {
Copy the line vertexes into the empty part of the "result polyline" to use as a scratch buffer.
memcpy (result, Verts, count*sizeof (Cpvect));
} else {
If a result array is not specified, reduce the input instead.
result = Verts;
}

Degenerate case, all poins is the same.
int start, end;
Cploopindexes (Verts, Count, &start, &end);
if (start = = end) {
if (first) (*first) = 0;
return 1;
}

SWAP (Result[0], Result[start]);
SWAP (result[1], result[end = = 0? Start:end]);

Cpvect a = result[0];
Cpvect B = result[1];

if (first) (*first) = start;
int resultcount = Qhullreduce (tol, result + 2, count-2, A, B, a, result + 1) + 1;
Cpassertsoft (Cppolyvalidate (result, Resultcount),
"Internal Error:cpconvexhull () and Cppolyvalidate () did not agree."
"Please report the error with as much info as you can.");
return resultcount;
}

Mark:alternate Block iterators

#if defined (__has_extension)
#if __has_extension (Blocks)

static void Iteratorfunc (void *ptr, void (^block) (void *ptr)) {block (PTR);}

void Cpspaceeachbody_b (Cpspace *space, Void (^block) (Cpbody *body)) {
Cpspaceeachbody (space, (Cpspacebodyiteratorfunc) iteratorfunc, block);
}

void Cpspaceeachshape_b (Cpspace *space, Void (^block) (Cpshape *shape)) {
Cpspaceeachshape (space, (Cpspaceshapeiteratorfunc) iteratorfunc, block);
}

void Cpspaceeachconstraint_b (Cpspace *space, Void (^block) (Cpconstraint *constraint)) {
Cpspaceeachconstraint (space, (Cpspaceconstraintiteratorfunc) iteratorfunc, block);
}

static void Bodyiteratorfunc (Cpbody *body, void *ptr, void (^block) (void *ptr)) {block (PTR);}

void Cpbodyeachshape_b (Cpbody *body, Void (^block) (Cpshape *shape)) {
Cpbodyeachshape (body, (Cpbodyshapeiteratorfunc) bodyiteratorfunc, block);
}

void Cpbodyeachconstraint_b (Cpbody *body, Void (^block) (Cpconstraint *constraint)) {
Cpbodyeachconstraint (body, (Cpbodyconstraintiteratorfunc) bodyiteratorfunc, block);
}

void Cpbodyeacharbiter_b (Cpbody *body, Void (^block) (Cparbiter *arbiter)) {
Cpbodyeacharbiter (body, (Cpbodyarbiteriteratorfunc) bodyiteratorfunc, block);
}

static void Nearestpointqueryiteratorfunc (Cpshape *shape, cpfloat distance, Cpvect Point, Cpspacenearestpointqueryblock block) {block (shape, distance, point);}
void Cpspacenearestpointquery_b (Cpspace *space, Cpvect Point, Cpfloat maxdistance, cplayers layers, Cpgroup Group, CpSpac Enearestpointqueryblock block) {
Cpspacenearestpointquery (space, point, maxdistance, Layers, group, (Cpspacenearestpointqueryfunc) NEARESTPOINTQUERYITERATORFUNC, block);
}

static void Segmentqueryiteratorfunc (Cpshape *shape, Cpfloat T, Cpvect N, cpspacesegmentqueryblock block) {block (shape, t , n);}
void Cpspacesegmentquery_b (Cpspace *space, cpvect start, Cpvect end, cplayers layers, Cpgroup Group, Cpspacesegmentqueryb Lock block) {
Cpspacesegmentquery (space, start, end, layers, group, (Cpspacesegmentqueryfunc) segmentqueryiteratorfunc, block);
}

void Cpspacebbquery_b (cpspace *space, Cpbb bb, cplayers layers, Cpgroup Group, cpspacebbqueryblock block) {
Cpspacebbquery (space, BB, Layers, Group, (Cpspacebbqueryfunc) iteratorfunc, block);
}

static void Shapequeryiteratorfunc (Cpshape *shape, Cpcontactpointset *points, Cpspaceshapequeryblock block) {block ( shape, points);}
Cpbool Cpspaceshapequery_b (cpspace *space, Cpshape *shape, cpspaceshapequeryblock block) {
Return Cpspaceshapequery (Space, Shape, (cpspaceshapequeryfunc) shapequeryiteratorfunc, block);
}

#endif
#endif

#include "chipmunk_ffi.h"

Chipmunk Geometric algorithm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.